summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2012-01-18 15:28:49 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-08 11:56:41 +0100
commitcd747c718c24c8c5f224bef365912b10c93285b0 (patch)
treef494608c0e8215899de144b00813f6dd05ad6528
parent751a2b4cd14990f15b7600705aa94a3e0e276830 (diff)
Implemented new c++ api for qtjsondb.
The old api was not removed yet, but was moved to a separate qt5 module. It will be removed as soon as the rest of jsondb code doesn't depend on it. Change-Id: Icf190f378df476c33c40142503518ca043001d17 Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
-rw-r--r--doc/src/index.qdoc9
-rw-r--r--modules/qt_jsondb.pri8
-rw-r--r--modules/qt_jsondbcompat.pri18
-rw-r--r--src/client/client.pro44
-rw-r--r--src/client/qjsondbauthrequest.cpp117
-rw-r--r--src/client/qjsondbauthrequest_p.h82
-rw-r--r--src/client/qjsondbconnection.cpp754
-rw-r--r--src/client/qjsondbconnection.h127
-rw-r--r--src/client/qjsondbconnection_p.h114
-rw-r--r--src/client/qjsondbglobal.h71
-rw-r--r--src/client/qjsondbobject.cpp204
-rw-r--r--src/client/qjsondbobject.h82
-rw-r--r--src/client/qjsondbreadrequest.cpp390
-rw-r--r--src/client/qjsondbreadrequest.h128
-rw-r--r--src/client/qjsondbreadrequest_p.h97
-rw-r--r--src/client/qjsondbrequest.cpp217
-rw-r--r--src/client/qjsondbrequest.h132
-rw-r--r--src/client/qjsondbrequest_p.h92
-rw-r--r--src/client/qjsondbstrings_p.h130
-rw-r--r--src/client/qjsondbwatcher.cpp432
-rw-r--r--src/client/qjsondbwatcher.h156
-rw-r--r--src/client/qjsondbwatcher_p.h95
-rw-r--r--src/client/qjsondbwriterequest.cpp328
-rw-r--r--src/client/qjsondbwriterequest.h107
-rw-r--r--src/client/qjsondbwriterequest_p.h82
-rw-r--r--src/clientcompat/clientcompat.pro42
-rw-r--r--src/clientcompat/jsondb-client.cpp (renamed from src/client/jsondb-client.cpp)0
-rw-r--r--src/clientcompat/jsondb-client.h (renamed from src/client/jsondb-client.h)0
-rw-r--r--src/clientcompat/jsondb-client_p.h (renamed from src/client/jsondb-client_p.h)0
-rw-r--r--src/clientcompat/jsondb-connection.cpp (renamed from src/client/jsondb-connection.cpp)0
-rw-r--r--src/clientcompat/jsondb-connection_p.h (renamed from src/client/jsondb-connection_p.h)0
-rw-r--r--src/clientcompat/jsondb-connection_p_p.h (renamed from src/client/jsondb-connection_p_p.h)0
-rw-r--r--src/clientcompat/jsondb-error.cpp (renamed from src/client/jsondb-error.cpp)0
-rw-r--r--src/clientcompat/jsondb-error.h (renamed from src/client/jsondb-error.h)0
-rw-r--r--src/clientcompat/jsondb-global.h (renamed from src/client/jsondb-global.h)0
-rw-r--r--src/clientcompat/jsondb-notification.cpp (renamed from src/client/jsondb-notification.cpp)0
-rw-r--r--src/clientcompat/jsondb-notification.h (renamed from src/client/jsondb-notification.h)0
-rw-r--r--src/clientcompat/jsondb-object.cpp (renamed from src/client/jsondb-object.cpp)2
-rw-r--r--src/clientcompat/jsondb-object.h (renamed from src/client/jsondb-object.h)0
-rw-r--r--src/clientcompat/jsondb-oneshot.cpp (renamed from src/client/jsondb-oneshot.cpp)0
-rw-r--r--src/clientcompat/jsondb-oneshot_p.h (renamed from src/client/jsondb-oneshot_p.h)0
-rw-r--r--src/clientcompat/jsondb-query.cpp (renamed from src/client/jsondb-query.cpp)0
-rw-r--r--src/clientcompat/jsondb-query.h (renamed from src/client/jsondb-query.h)0
-rw-r--r--src/clientcompat/jsondb-strings_p.h (renamed from src/client/jsondb-strings_p.h)0
-rw-r--r--src/common/jsondb-error.h2
-rw-r--r--src/common/jsondb-global.h2
-rw-r--r--src/common/jsondb-strings.h2
-rw-r--r--src/imports/jsondb-listmodel/jsondb-listmodel.pro2
-rw-r--r--src/imports/jsondb/jsondb.pro4
-rw-r--r--src/imports/qimportbase.pri2
-rw-r--r--src/jsonstream/jsonstream.cpp145
-rw-r--r--src/jsonstream/jsonstream.h83
-rw-r--r--src/jsonstream/jsonstream.pri2
-rw-r--r--src/jsonstream/jsonstream.pro14
-rw-r--r--src/src.pro3
-rw-r--r--sync.profile11
-rw-r--r--tests/auto/client/client.pro2
-rw-r--r--tests/auto/jsondb-listmodel/jsondb-listmodel.pro2
-rw-r--r--tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro2
-rw-r--r--tests/auto/jsondblistmodel/jsondblistmodel.pro2
-rw-r--r--tests/auto/jsondbnotification/jsondbnotification.pro2
-rw-r--r--tests/auto/jsondbpartition/jsondbpartition.pro2
-rw-r--r--tests/auto/jsondbqueryobject/jsondbqueryobject.pro2
-rw-r--r--tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro2
-rw-r--r--tests/benchmarks/client/client.pro2
-rw-r--r--tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro2
-rw-r--r--tests/shared/shared.pri8
-rw-r--r--tools/jsondb-client/client.cpp330
-rw-r--r--tools/jsondb-client/client.h33
-rw-r--r--tools/jsondb-client/jsondb-client.pro3
-rw-r--r--tools/tools.pro2
71 files changed, 4497 insertions, 231 deletions
diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc
index 13cd50da..a01b5fa6 100644
--- a/doc/src/index.qdoc
+++ b/doc/src/index.qdoc
@@ -115,18 +115,15 @@ sets.
\section2 Notifications
Notifications are created, updated, and removed by using a
-\l{JsonDbClient::registerNotification()}{dedicated api} which
+\l{QJsonDbConnection::addWatcher()}{dedicated api} which
takes a query expression and a list of actions as an argument. There are
actions available that allow watching for objects being created, updated or
removed from a database.
When a notification matches an action performed on the database, the
-application is notified through one of the client APIs. The notification is
-identified by the UUID of the matching notification. The object being acted
-upon and the type of the action are delivered along with the notification UUID
-to the client.
+QJsonDbWatcher::notificationsAvailable() signal is emitted.
-See also \l{JsonDbNotification}
+See also \l{QJsonDbWatcher}
\section1 Examples
diff --git a/modules/qt_jsondb.pri b/modules/qt_jsondb.pri
index 040aacb9..ffdf582b 100644
--- a/modules/qt_jsondb.pri
+++ b/modules/qt_jsondb.pri
@@ -4,15 +4,15 @@ QT.jsondb.MAJOR_VERSION = 1
QT.jsondb.MINOR_VERSION = 0
QT.jsondb.PATCH_VERSION = 0
-QT.jsondb.name = QtAddOnJsonDb
+QT.jsondb.name = QtJsonDb
QT.jsondb.bins = $$QT_MODULE_BIN_BASE
-QT.jsondb.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtAddOnJsonDb
-QT.jsondb.private_includes = $$QT_MODULE_INCLUDE_BASE/QtAddOnJsonDb/$$QT.jsondb.VERSION
+QT.jsondb.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtJsonDb
+QT.jsondb.private_includes = $$QT_MODULE_INCLUDE_BASE/QtJsonDb/$$QT.jsondb.VERSION
QT.jsondb.sources = $$QT_MODULE_BASE/src
QT.jsondb.libs = $$QT_MODULE_LIB_BASE
QT.jsondb.plugins = $$QT_MODULE_PLUGIN_BASE
QT.jsondb.imports = $$QT_MODULE_IMPORT_BASE
-QT.jsondb.depends = core network declarative jsondbqson
+QT.jsondb.depends = core network declarative
QT_CONFIG += jsondb
}
diff --git a/modules/qt_jsondbcompat.pri b/modules/qt_jsondbcompat.pri
new file mode 100644
index 00000000..0d11b8ea
--- /dev/null
+++ b/modules/qt_jsondbcompat.pri
@@ -0,0 +1,18 @@
+!win32 {
+QT.jsondbcompat.VERSION = 1.0.0
+QT.jsondbcompat.MAJOR_VERSION = 1
+QT.jsondbcompat.MINOR_VERSION = 0
+QT.jsondbcompat.PATCH_VERSION = 0
+
+QT.jsondbcompat.name = QtJsonDbCompat
+QT.jsondbcompat.bins = $$QT_MODULE_BIN_BASE
+QT.jsondbcompat.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtJsonDbCompat
+QT.jsondbcompat.private_includes = $$QT_MODULE_INCLUDE_BASE/QtJsonDbCompat/$$QT.jsondbcompat.VERSION
+QT.jsondbcompat.sources = $$QT_MODULE_BASE/src
+QT.jsondbcompat.libs = $$QT_MODULE_LIB_BASE
+QT.jsondbcompat.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.jsondbcompat.imports = $$QT_MODULE_IMPORT_BASE
+QT.jsondbcompat.depends = core network declarative
+
+QT_CONFIG += jsondbcompat
+}
diff --git a/src/client/client.pro b/src/client/client.pro
index 37a915d8..5fac890d 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -7,36 +7,40 @@ load(qt_module_config)
DESTDIR = $$QT.jsondb.libs
VERSION = $$QT.jsondb.VERSION
-DEFINES += QT_ADDON_JSONDB_LIB
+DEFINES += QT_JSONDB_LIB
QT = core network
CONFIG += module create_prl
MODULE_PRI = ../../modules/qt_jsondb.pri
-include(../common/common.pri)
+include(../jsonstream/jsonstream.pri)
-HEADERS += qtaddonjsondbversion.h
+HEADERS += qtjsondbversion.h
HEADERS += \
- jsondb-error.h \
- jsondb-client.h \
- jsondb-object.h \
- jsondb-client_p.h \
- jsondb-connection_p.h \
- jsondb-connection_p_p.h \
- jsondb-query.h \
- jsondb-oneshot_p.h \
- jsondb-strings_p.h \
- jsondb-notification.h
+ qjsondbglobal.h \
+ qjsondbstrings_p.h \
+ qjsondbconnection_p.h \
+ qjsondbconnection.h \
+ qjsondbrequest_p.h \
+ qjsondbrequest.h \
+ qjsondbreadrequest_p.h \
+ qjsondbreadrequest.h \
+ qjsondbwriterequest_p.h \
+ qjsondbwriterequest.h \
+ qjsondbauthrequest_p.h \
+ qjsondbwatcher_p.h \
+ qjsondbwatcher.h \
+ qjsondbobject.h
SOURCES += \
- jsondb-error.cpp \
- jsondb-client.cpp \
- jsondb-object.cpp \
- jsondb-connection.cpp \
- jsondb-query.cpp \
- jsondb-oneshot.cpp \
- jsondb-notification.cpp
+ qjsondbconnection.cpp \
+ qjsondbrequest.cpp \
+ qjsondbreadrequest.cpp \
+ qjsondbwriterequest.cpp \
+ qjsondbauthrequest.cpp \
+ qjsondbwatcher.cpp \
+ qjsondbobject.cpp
mac:QMAKE_FRAMEWORK_BUNDLE_NAME = $$QT.jsondb.name
diff --git a/src/client/qjsondbauthrequest.cpp b/src/client/qjsondbauthrequest.cpp
new file mode 100644
index 00000000..4df0acea
--- /dev/null
+++ b/src/client/qjsondbauthrequest.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbauthrequest_p.h"
+#include "qjsondbstrings_p.h"
+
+#include <QJsonArray>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbAuthRequestPrivate : public QJsonDbRequestPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbAuthRequest)
+public:
+ QJsonDbAuthRequestPrivate(QJsonDbAuthRequest *q);
+
+ QJsonObject getRequest() const;
+ void handleResponse(const QJsonObject &);
+ void handleError(int, const QString &);
+
+ QByteArray token;
+};
+
+QJsonDbAuthRequestPrivate::QJsonDbAuthRequestPrivate(QJsonDbAuthRequest *q)
+ : QJsonDbRequestPrivate(q)
+{
+}
+
+QJsonDbAuthRequest::QJsonDbAuthRequest(QObject *parent)
+ : QJsonDbRequest(new QJsonDbAuthRequestPrivate(this), parent)
+{
+}
+
+QJsonDbAuthRequest::~QJsonDbAuthRequest()
+{
+}
+
+QByteArray QJsonDbAuthRequest::token() const
+{
+ Q_D(const QJsonDbAuthRequest);
+ return d->token;
+}
+
+void QJsonDbAuthRequest::setToken(const QByteArray &token)
+{
+ Q_D(QJsonDbAuthRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->token = token;
+}
+
+QJsonObject QJsonDbAuthRequestPrivate::getRequest() const
+{
+ QJsonObject request;
+ request.insert(JsonDbStrings::Protocol::action(), JsonDbStrings::Protocol::token());
+ request.insert(JsonDbStrings::Protocol::object(), QString::fromLatin1(token));
+ request.insert(JsonDbStrings::Protocol::requestId(), requestId);
+ return request;
+}
+
+void QJsonDbAuthRequestPrivate::handleResponse(const QJsonObject &response)
+{
+ Q_Q(QJsonDbAuthRequest);
+ Q_UNUSED(response);
+ setStatus(QJsonDbRequest::Receiving);
+ emit q->started();
+ setStatus(QJsonDbRequest::Finished);
+ emit q->finished();
+}
+
+void QJsonDbAuthRequestPrivate::handleError(int code, const QString &message)
+{
+ Q_Q(QJsonDbAuthRequest);
+ setStatus(QJsonDbRequest::Error);
+ emit q->error(QJsonDbRequest::ErrorCode(code), message);
+}
+
+#include "moc_qjsondbauthrequest_p.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbauthrequest_p.h b/src/client/qjsondbauthrequest_p.h
new file mode 100644
index 00000000..a8d16cc5
--- /dev/null
+++ b/src/client/qjsondbauthrequest_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_AUTH_REQUEST_H
+#define JSONDB_AUTH_REQUEST_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+
+#include "qjsondbrequest_p.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbAuthRequestPrivate;
+class QJsonDbAuthRequest : public QJsonDbRequest
+{
+ Q_OBJECT
+ Q_PROPERTY(QByteArray token READ token WRITE setToken)
+
+public:
+ QJsonDbAuthRequest(QObject *parent = 0);
+ ~QJsonDbAuthRequest();
+
+ QByteArray token() const;
+ void setToken(const QByteArray &);
+
+private:
+ Q_DISABLE_COPY(QJsonDbAuthRequest)
+ Q_DECLARE_PRIVATE(QJsonDbAuthRequest)
+};
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_AUTH_REQUEST_H
diff --git a/src/client/qjsondbconnection.cpp b/src/client/qjsondbconnection.cpp
new file mode 100644
index 00000000..49828fe8
--- /dev/null
+++ b/src/client/qjsondbconnection.cpp
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbconnection_p.h"
+#include "qjsondbwriterequest.h"
+#include "qjsondbrequest_p.h"
+#include "qjsondbauthrequest_p.h"
+#include "qjsondbwatcher_p.h"
+#include "qjsondbstrings_p.h"
+#include "qjsondbobject.h"
+
+#include <qcoreevent.h>
+#include <qtimer.h>
+#include <qjsonarray.h>
+
+/*!
+ \macro QT_USE_NAMESPACE_JSONDB
+ \inmodule QtJsonDb
+
+ This macro expands to using jsondb namespace and makes jsondb namespace
+ visible to C++ source code.
+
+ \code
+ #include <QtJsonDb/qjsondbglobal.h>
+ QT_USE_NAMESPACE_JSONDB
+ \endcode
+
+ To declare the class without including the declaration of the class:
+
+ \code
+ #include <QtJsonDb/qjsondbglobal.h>
+ QT_BEGIN_NAMESPACE_JSONDB
+ class QJsonDbConnection;
+ QT_END_NAMESPACE_JSONDB
+ QT_USE_NAMESPACE_JSONDB
+ \endcode
+*/
+
+/*!
+ \macro QT_BEGIN_NAMESPACE_JSONDB
+ \inmodule QtJsonDb
+
+ This macro begins a jsondb namespace. All forward declarations of QtJsonDb
+ classes need to be wrapped in \c QT_BEGIN_NAMESPACE_JSONDB and \c
+ QT_END_NAMESPACE_JSONDB.
+
+ This macro includes QT_BEGIN_NAMESPACE, if Qt was compiled with namespace.
+
+ \sa QT_USE_NAMESPACE_JSONDB, QT_END_NAMESPACE_JSONDB
+*/
+
+/*!
+ \macro QT_END_NAMESPACE_JSONDB
+ \inmodule QtJsonDb
+
+ This macro ends a jsondb namespace. All forward declarations of QtJsonDb classes need to
+ be wrapped in \c QT_BEGIN_NAMESPACE_JSONDB and \c QT_END_NAMESPACE_JSONDB.
+
+ This macro includes QT_END_NAMESPACE, if Qt was compiled with namespace.
+
+ \sa QT_USE_NAMESPACE_JSONDB, QT_BEGIN_NAMESPACE_JSONDB
+*/
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+/*!
+ \class QJsonDbConnection
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbConnection class provides a client interface which connects to the QJsonDb server.
+
+ The connection is done using the local socket (unix domain socket)
+ \l{QJsonDbConnection::socketName}{socketName}.
+
+ The connection has a queue of requests, and each request that is meant to
+ be \l{QJsonDbConnection::send()}{sent} is appended to the queue, which
+ guarantees order of execution of requests. It is possible to add requests
+ to the queue, even if the connection to the database is not yet established
+ - requests will be queued locally and executed after the connection is
+ complete.
+
+ The connection has to be initiated explicitly by calling connectToServer().
+ If \l{QJsonDbConnection::autoReconnectEnabled}{autoReconnectEnabled} property is set to
+ true (by default), QJsonDbConnection object attempts to maintain the
+ connection alive - by reconnecting again whenever the local socket
+ connection is dropped, unless the connection was dropped due to
+ a critical error (see \l{QJsonDbConnection::error()}{error()} signal).
+
+ \code
+ QtJsonDb::QJsonDbConnection *connection = new QtJsonDb::QJsonDbConnection;
+ QObject::connect(connection, SIGNAL(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString))),
+ this, SIGNAL(onConnectionError(QtJsonDb::QJsonDbConnection::ErrorCode,QString)));
+ connection->connectToServer();
+ \endcode
+*/
+/*!
+ \enum QJsonDbConnection::ErrorCode
+
+ This enum describes database connection errors.
+
+ \value NoError
+*/
+/*!
+ \enum QJsonDbConnection::Status
+
+ This enum describes current database connection status.
+
+ \value Unconnected Not connected.
+ \value Connecting Connection to the database is being established.
+ \value Connected Connection established.
+*/
+
+QJsonDbConnectionPrivate::QJsonDbConnectionPrivate(QJsonDbConnection *q)
+ : q_ptr(q), status(QJsonDbConnection::Unconnected), autoReconnectEnabled(true),
+ explicitDisconnect(false), timeoutTimer(q), stream(0), lastRequestId(0)
+{
+ timeoutTimer.setSingleShot(true);
+ timeoutTimer.setTimerType(Qt::VeryCoarseTimer);
+ QObject::connect(&timeoutTimer, SIGNAL(timeout()), q, SLOT(_q_onTimer()));
+ defaultAuthenticationToken = qgetenv("JSONDB_TOKEN");
+ socket = new QLocalSocket(q);
+ QObject::connect(socket, SIGNAL(disconnected()), q_ptr, SLOT(_q_onDisconnected()));
+ QObject::connect(socket, SIGNAL(connected()), q_ptr, SLOT(_q_onConnected()));
+ QObject::connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
+ q_ptr, SLOT(_q_onError(QLocalSocket::LocalSocketError)));
+ stream = new JsonStream::JsonStream(q);
+ stream->setDevice(socket);
+ QObject::connect(stream, SIGNAL(receive(QJsonObject)),
+ q_ptr, SLOT(_q_onReceivedObject(QJsonObject)));
+}
+
+void QJsonDbConnectionPrivate::_q_onConnected()
+{
+ Q_Q(QJsonDbConnection);
+ Q_ASSERT(status == QJsonDbConnection::Connecting);
+ QByteArray token = authenticationToken.isEmpty() ? defaultAuthenticationToken : authenticationToken;
+ if (!token.isEmpty()) {
+ status = QJsonDbConnection::Authenticating;
+ emit q->statusChanged(status);
+ QJsonDbAuthRequest *request = new QJsonDbAuthRequest(q);
+ request->QJsonDbRequest::d_func()->internal = true;
+ request->setToken(token);
+ QObject::connect(request, SIGNAL(finished()), q, SLOT(_q_onAuthFinished()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_onAuthError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ // auto delete request after it's complete
+ QObject::connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ q->send(request);
+ return;
+ }
+ status = QJsonDbConnection::Connected;
+ emit q->statusChanged(status);
+ emit q->connected();
+
+ // reactivate all watchers
+ reactivateAllWatchers();
+ handleRequestQueue();
+}
+
+void QJsonDbConnectionPrivate::_q_onDisconnected()
+{
+ Q_Q(QJsonDbConnection);
+ if (currentRequest) {
+ QJsonDbRequestPrivate *drequest = currentRequest.data()->d_func();
+ drequest->setStatus(QJsonDbRequest::Error);
+ emit currentRequest.data()->error(QJsonDbRequest::DatabaseConnectionError, QString());
+ pendingRequests.prepend(currentRequest);
+ currentRequest.clear();
+ }
+ // deactivate all watchers
+ QMap<QString, QWeakPointer<QJsonDbWatcher> >::iterator it;
+ for (it = watchers.begin(); it != watchers.end();) {
+ QJsonDbWatcher *watcher = it.value().data();
+ if (!watcher) {
+ it = watchers.erase(it);
+ continue;
+ }
+ QJsonDbWatcherPrivate *dwatcher = watcher->d_func();
+ dwatcher->setStatus(QJsonDbWatcher::Activating); // emits stateChanged
+ ++it;
+ }
+
+ if (status == QJsonDbConnection::Unconnected) {
+ // an error occured (e.g. auth error), we should not reconnect.
+ emit q->disconnected();
+ return;
+ }
+
+ QJsonDbConnection::Status newStatus;
+ if (shouldAutoReconnect()) {
+ newStatus = QJsonDbConnection::Connecting;
+ if (!timeoutTimer.isActive()) {
+ timeoutTimer.setInterval(5000);
+ timeoutTimer.start();
+ }
+ } else {
+ newStatus = QJsonDbConnection::Unconnected;
+ }
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged(status);
+ }
+ emit q->disconnected();
+}
+
+void QJsonDbConnectionPrivate::_q_onError(QLocalSocket::LocalSocketError error)
+{
+ switch (error) {
+ case QLocalSocket::ServerNotFoundError:
+ case QLocalSocket::ConnectionRefusedError:
+ case QLocalSocket::PeerClosedError:
+ case QLocalSocket::SocketAccessError:
+ case QLocalSocket::SocketResourceError:
+ case QLocalSocket::SocketTimeoutError:
+ case QLocalSocket::ConnectionError:
+ case QLocalSocket::UnsupportedSocketOperationError:
+ case QLocalSocket::UnknownSocketError:
+ case QLocalSocket::OperationError:
+ _q_onDisconnected();
+ break;
+ case QLocalSocket::DatagramTooLargeError:
+ qWarning("QJsonDbConnectionPrivate: datagram is too large.");
+ break;
+ }
+}
+
+void QJsonDbConnectionPrivate::_q_onTimer()
+{
+ if (status == QJsonDbConnection::Connecting)
+ socket->connectToServer(serverSocketName());
+}
+
+void QJsonDbConnectionPrivate::handleRequestQueue()
+{
+ if (currentRequest)
+ return;
+ if (status != QJsonDbConnection::Connected)
+ return;
+
+ if (pendingRequests.isEmpty())
+ return;
+ QWeakPointer<QJsonDbRequest> request;
+ do { request = pendingRequests.takeFirst(); } while (!request && !pendingRequests.isEmpty());
+ if (request) {
+ Q_ASSERT(request.data()->status() == QJsonDbRequest::Queued);
+ QJsonDbRequestPrivate *drequest = request.data()->d_func();
+ Q_ASSERT(drequest != 0);
+ drequest->setRequestId(++lastRequestId);
+ drequest->setStatus(QJsonDbRequest::Sent);
+ QJsonObject req = drequest->getRequest();
+ if (!req.isEmpty()) {
+ currentRequest = request;
+ stream->send(req);
+ }
+ }
+}
+
+void QJsonDbConnectionPrivate::_q_onReceivedObject(const QJsonObject &object)
+{
+ if (object.contains(JsonDbStrings::Property::notify())) {
+ QString notifyUuid = object.value(JsonDbStrings::Property::uuid()).toString();
+ QJsonObject sub = object.value(JsonDbStrings::Property::notify()).toObject();
+ QString action = sub.value(JsonDbStrings::Protocol::action()).toString();
+ QJsonObject object = sub.value(JsonDbStrings::Protocol::object()).toObject();
+ QMap<QString, QWeakPointer<QJsonDbWatcher> >::iterator it = watchers.find(notifyUuid);
+ if (it != watchers.end()) {
+ QJsonDbWatcher *watcher = it.value().data();
+ if (!watcher) {
+ qWarning("QJsonDbConnection: received notification for already deleted watcher");
+ watchers.erase(it);
+ return;
+ }
+ QJsonDbWatcher::Action actionType;
+ if (action == JsonDbStrings::Notification::actionCreate())
+ actionType = QJsonDbWatcher::Created;
+ else if (action == JsonDbStrings::Notification::actionUpdate())
+ actionType = QJsonDbWatcher::Updated;
+ else if (action == JsonDbStrings::Notification::actionRemove())
+ actionType = QJsonDbWatcher::Removed;
+ else
+ Q_ASSERT(false);
+ watcher->d_func()->handleNotification(actionType, object);
+ } else {
+ qWarning("QJsonDbConnection: received notification for unknown watcher");
+ }
+ } else if (currentRequest) {
+ QJsonDbRequestPrivate *drequest = currentRequest.data()->d_func();
+ currentRequest.clear();
+ int requestId = static_cast<int>(object.value(JsonDbStrings::Protocol::requestId()).toDouble());
+ Q_ASSERT(requestId == drequest->requestId);
+ Q_UNUSED(requestId);
+ QJsonValue result = object.value(JsonDbStrings::Protocol::result());
+ if (result.isObject()) {
+ drequest->handleResponse(result.toObject());
+ } else if (result.isString()) {
+ // ### TODO: meeeh, hack for response to authentication token
+ drequest->handleResponse(QJsonObject());
+ } else {
+ QJsonObject error = object.value(JsonDbStrings::Protocol::error()).toObject();
+ int code = static_cast<int>(error.value(JsonDbStrings::Protocol::errorCode()).toDouble());
+ QString message = error.value(JsonDbStrings::Protocol::errorMessage()).toString();
+ drequest->handleError(code, message);
+ }
+ handleRequestQueue();
+ } else {
+ qWarning("QJsonDbConnection: got a response to already deleted request object");
+ handleRequestQueue();
+ }
+}
+
+void QJsonDbConnectionPrivate::_q_onAuthFinished()
+{
+ Q_Q(QJsonDbConnection);
+ Q_ASSERT(status == 2);
+ status = QJsonDbConnection::Connected;
+ emit q->statusChanged(status);
+ reactivateAllWatchers();
+ handleRequestQueue();
+}
+
+void QJsonDbConnectionPrivate::_q_onAuthError(QtJsonDb::QJsonDbRequest::ErrorCode, const QString &message)
+{
+ Q_Q(QJsonDbConnection);
+ status = QJsonDbConnection::Unconnected;
+ emit q->statusChanged(status);
+ explicitDisconnect = true;
+ socket->disconnectFromServer();
+}
+
+/*!
+ Constructs a new connection object with a given \a parent.
+*/
+QJsonDbConnection::QJsonDbConnection(QObject *parent)
+ : QObject(parent), d_ptr(new QJsonDbConnectionPrivate(this))
+{
+}
+
+/*!
+ Destroys the JsonDbConnection object.
+*/
+QJsonDbConnection::~QJsonDbConnection()
+{
+ disconnectFromServer();
+}
+
+/*!
+ \property QJsonDbConnection::socketName
+ Specifies the local socket name that is used to establish the connection.
+
+ If this property is not set, the default socket name is used.
+
+ \sa connectToServer()
+*/
+void QJsonDbConnection::setSocketName(const QString &socketName)
+{
+ Q_D(QJsonDbConnection);
+ if (d->status != QJsonDbConnection::Unconnected)
+ qWarning("QJsonDbConnection: cannot set socket name on active connection");
+ d->socketName = socketName;
+}
+
+QString QJsonDbConnection::socketName() const
+{
+ Q_D(const QJsonDbConnection);
+ return d->socketName;
+}
+
+/*!
+ \property QJsonDbConnection::status
+ Specifies the current connection state.
+ \sa statusChanged(), connected(), disconnected(), error()
+*/
+QJsonDbConnection::Status QJsonDbConnection::status() const
+{
+ Q_D(const QJsonDbConnection);
+ return d->status;
+}
+
+/*!
+ \property QJsonDbConnection::autoReconnectEnabled
+ Specifies whether the connection should be re-established if it was droppped.
+
+ This property is set to true by default.
+
+ \sa connectToServer(), disconnectFromServer()
+*/
+void QJsonDbConnection::setAutoReconnectEnabled(bool value)
+{
+ Q_D(QJsonDbConnection);
+ d->autoReconnectEnabled = value;
+}
+
+bool QJsonDbConnection::isAutoReconnectEnabled() const
+{
+ Q_D(const QJsonDbConnection);
+ return d->autoReconnectEnabled;
+}
+
+/*!
+ Returns the queue of request objects that are pending to be sent.
+ \sa cancel()
+*/
+QList<QJsonDbRequest *> QJsonDbConnection::pendingRequests() const
+{
+ Q_D(const QJsonDbConnection);
+ QList<QJsonDbRequest *> requests;
+ requests.reserve(d->pendingRequests.size());
+ foreach (const QWeakPointer<QJsonDbRequest> &request, d->pendingRequests) {
+ if (request && !request.data()->d_func()->internal)
+ requests.append(request.data());
+ }
+ return requests;
+}
+
+/*!
+ Attempts to establish a connection to the database.
+
+ \sa autoReconnectEnabled, status, disconnectFromServer()
+*/
+void QJsonDbConnection::connectToServer()
+{
+ Q_D(QJsonDbConnection);
+ if (d->status != QJsonDbConnection::Unconnected)
+ return;
+ Q_ASSERT(d->socket->state() == QLocalSocket::UnconnectedState);
+
+ d->explicitDisconnect = false;
+ d->status = QJsonDbConnection::Connecting;
+ emit statusChanged(d->status);
+
+ d->socket->connectToServer(d->serverSocketName());
+}
+
+/*!
+ Disconnects from the server.
+
+ \sa autoReconnectEnabled, status, connectToServer()
+*/
+void QJsonDbConnection::disconnectFromServer()
+{
+ Q_D(QJsonDbConnection);
+ if (d->status == QJsonDbConnection::Unconnected)
+ return;
+ d->explicitDisconnect = true;
+ d->socket->disconnectFromServer();
+}
+
+/*!
+ Appends the given \a request to the queue and attempts to send it.
+
+ Returns true if the request was successfully added to the queue.
+
+ \sa cancel()
+*/
+bool QJsonDbConnection::send(QJsonDbRequest *request)
+{
+ Q_D(QJsonDbConnection);
+ if (!request)
+ return false;
+ QJsonDbRequestPrivate *drequest = request->d_func();
+ if (drequest->status >= QJsonDbRequest::Queued) {
+ qWarning("QJsonDbConnection: cannot send request that is already being processed.");
+ return false;
+ }
+ drequest->setStatus(QJsonDbRequest::Queued);
+ if (drequest->internal)
+ d->pendingRequests.prepend(QWeakPointer<QJsonDbRequest>(request));
+ else
+ d->pendingRequests.append(QWeakPointer<QJsonDbRequest>(request));
+ if (d->status == QJsonDbConnection::Connected)
+ d->handleRequestQueue();
+ return true;
+}
+
+/*!
+ Cancels the given \a request.
+
+ It is only possible to cancel request that was queued, but not sent to the
+ server yet, i.e. a request in the QJsonDbRequest::Queued state.
+
+ Returns true if the request was successfully canceled.
+
+ \sa cancelPendingRequests(), pendingRequests(), QJsonDbRequest::status
+*/
+bool QJsonDbConnection::cancel(QJsonDbRequest *request)
+{
+ Q_D(QJsonDbConnection);
+ if (!request)
+ return false;
+ switch (request->status()) {
+ case QJsonDbRequest::Inactive:
+ case QJsonDbRequest::Error:
+ case QJsonDbRequest::Finished:
+ case QJsonDbRequest::Canceled:
+ qWarning("QJsonDbConnection: cannot cancel request that was not added to connection.");
+ return true;
+ case QJsonDbRequest::Sent:
+ case QJsonDbRequest::Receiving:
+ qWarning("QJsonDbConnection: cannot cancel request that was already sent.");
+ return false;
+ case QJsonDbRequest::Queued:
+ if (!d->pendingRequests.removeOne(request)) {
+ qWarning("QJsonDbConnection: cannot cancel request that doesn't belong to this connection.");
+ return false;
+ }
+ request->d_func()->setStatus(QJsonDbRequest::Canceled);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Cancels all pending requests that were in the request queue.
+
+ \sa pendingRequests(), cancel()
+*/
+void QJsonDbConnection::cancelPendingRequests()
+{
+ Q_D(QJsonDbConnection);
+ QList<QWeakPointer<QJsonDbRequest> > list;
+ list.swap(d->pendingRequests);
+ for (int i = 0; i < list.size(); ++i) {
+ QWeakPointer<QJsonDbRequest> request = list.at(i);
+ if (request && request.data()->d_func()->internal)
+ d->pendingRequests.append(request);
+ }
+ for (int i = 0; i < list.size(); ++i) {
+ QWeakPointer<QJsonDbRequest> request = list.at(i);
+ if (request) {
+ QJsonDbRequestPrivate *drequest = request.data()->d_func();
+ if (!drequest->internal)
+ drequest->setStatus(QJsonDbRequest::Canceled);
+ }
+ }
+}
+
+void QJsonDbConnectionPrivate::reactivateAllWatchers()
+{
+ QMap<QString, QWeakPointer<QJsonDbWatcher> >::iterator it;
+ for (it = watchers.begin(); it != watchers.end();) {
+ QJsonDbWatcher *watcher = it.value().data();
+ if (!watcher) {
+ it = watchers.erase(it);
+ continue;
+ }
+ initWatcher(watcher);
+ ++it;
+ }
+}
+
+void QJsonDbConnectionPrivate::initWatcher(QJsonDbWatcher *watcher)
+{
+ Q_Q(QJsonDbConnection);
+ QJsonDbWatcherPrivate *dwatcher = watcher->d_func();
+ dwatcher->connection = q;
+ dwatcher->setStatus(QJsonDbWatcher::Activating);
+
+ // make notification object
+ QJsonDbObject object;
+ object.insert(JsonDbStrings::Property::type(), QJsonValue(JsonDbStrings::Types::notification()));
+ object.insert(JsonDbStrings::Property::query(), QJsonValue(dwatcher->query));
+ // ### TODO: in the future pass initialStateNumber to the server
+ // object.insert(JsonDbStrings::Property::initialStateNumber(),
+ // qMax(dwatcher->lastStateNumber, dwatcher->initialStateNumber));
+ QJsonArray actions;
+ if (dwatcher->actions & QJsonDbWatcher::Created)
+ actions.append(JsonDbStrings::Notification::actionCreate());
+ if (dwatcher->actions & QJsonDbWatcher::Updated)
+ actions.append(JsonDbStrings::Notification::actionUpdate());
+ if (dwatcher->actions & QJsonDbWatcher::Removed)
+ actions.append(JsonDbStrings::Notification::actionRemove());
+ object.insert(JsonDbStrings::Property::actions(), actions);
+ object.insert(JsonDbStrings::Protocol::partition(), QJsonValue(dwatcher->partition));
+ object.insert(JsonDbStrings::Property::uuid(), QJsonValue(dwatcher->uuid));
+
+ Q_ASSERT(!dwatcher->uuid.isEmpty());
+ Q_ASSERT(!QUuid(dwatcher->uuid).isNull());
+ watchers.insert(dwatcher->uuid, QWeakPointer<QJsonDbWatcher>(watcher));
+
+ QList<QJsonObject> objects;
+ objects.append(object);
+ // now make a request object
+ QJsonDbWriteRequest *request = new QJsonDbWriteRequest(q);
+ request->setObjects(objects);
+ request->QJsonDbRequest::d_func()->internal = true;
+ request->setPartition(JsonDbStrings::Partition::ephemeral());
+ QObject::connect(request, SIGNAL(finished()), watcher, SLOT(_q_onFinished()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ watcher, SLOT(_q_onError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ // auto delete request after it's complete
+ QObject::connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ q->send(request);
+}
+
+void QJsonDbConnectionPrivate::removeWatcher(QJsonDbWatcher *watcher)
+{
+ Q_Q(QJsonDbConnection);
+ if (!watcher)
+ return;
+
+ QJsonDbWatcherPrivate *dwatcher = watcher->d_func();
+ if (!watchers.take(dwatcher->uuid))
+ return;
+
+ QJsonObject object;
+ object.insert(JsonDbStrings::Property::uuid(), dwatcher->uuid);
+ object.insert(JsonDbStrings::Property::version(), dwatcher->version);
+
+ // create a request to remove notification object
+ // This time we don't care about the response to that removal request.
+ QJsonDbWriteRequest *request = new QJsonDbRemoveRequest(object);
+ request->QJsonDbRequest::d_func()->internal = true;
+ request->setPartition(JsonDbStrings::Partition::ephemeral());
+ // auto delete request after it's complete
+ QObject::connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ q->send(request);
+
+ dwatcher->connection.clear();
+ dwatcher->setStatus(QJsonDbWatcher::Inactive);
+}
+
+/*!
+ Registers and activates the given \a watcher withing the database connection.
+
+ Returns true if the watcher was registered.
+
+ Note however that registering a watcher doesn't necessery mean it was
+ activated sucessfully, but QJsonDbWatcher::status property should be used to
+ detect that.
+
+ \sa removeWatcher()
+*/
+bool QJsonDbConnection::addWatcher(QJsonDbWatcher *watcher)
+{
+ Q_D(QJsonDbConnection);
+ if (!watcher)
+ return false;
+ QJsonDbWatcherPrivate *dwatcher = watcher->d_func();
+ if (dwatcher->status != QJsonDbWatcher::Inactive) {
+ qWarning("QJsonDbConnection: cannot add watcher that is already active.");
+ return false;
+ }
+ d->initWatcher(watcher);
+ return true;
+}
+
+/*!
+ Unregisters and deactivates the given \a watcher.
+
+ After being unregistered, the watcher no longer emits notifications.
+
+ Returns true if succeeds (e.g. if watcher was previously registered).
+
+ \sa addWatcher()
+*/
+bool QJsonDbConnection::removeWatcher(QJsonDbWatcher *watcher)
+{
+ Q_D(QJsonDbConnection);
+ if (!watcher)
+ return true;
+ QJsonDbWatcherPrivate *dwatcher = watcher->d_func();
+ if (dwatcher->status == QJsonDbWatcher::Inactive) {
+ qWarning("QJsonDbConnection: cannot remove watcher that is not active.");
+ return false;
+ }
+ if (!d->watchers.contains(dwatcher->uuid)) {
+ qWarning("QJsonDbConnection: cannot remove watcher that was not added.");
+ return false;
+ }
+ d->removeWatcher(watcher);
+ return true;
+}
+
+/*!
+ \fn void QJsonDbConnection::connected()
+
+ This signal is emitted when the connection to the database was established.
+
+ \sa status, disconnected(), error()
+*/
+/*!
+ \fn void QJsonDbConnection::disconnected()
+
+ This signal is emitted when the connection to the database was dropped. If
+ the autoReconnectEnabled property is set to true, a new connection attempt will be
+ made.
+
+ \sa autoReconnectEnabled, status, connected(), error()
+*/
+/*!
+ \fn QJsonDbConnection::error(QtJsonDb::QJsonDbConnection::ErrorCode error, const QString &message)
+
+ This signal is emitted when a connection error occured. \a error and \a
+ message give more information on the cause of the error.
+
+ Note that if the autoReconnectEnabled property is set to true, a new connection
+ attempt will be made.
+
+ \sa autoReconnectEnabled, status, connectToServer()
+*/
+/*!
+ \fn void QJsonDbConnection::statusChanged(QtJsonDb::QJsonDbConnection::Status newStatus)
+
+ This signal is emitted when a connection state changes to \a newStatus.
+
+ \sa status
+*/
+#include "moc_qjsondbconnection.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbconnection.h b/src/client/qjsondbconnection.h
new file mode 100644
index 00000000..6e7ad045
--- /dev/null
+++ b/src/client/qjsondbconnection.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_CONNECTION_H
+#define JSONDB_CONNECTION_H
+
+#include <QtCore/QObject>
+
+#include <QtJsonDb/qjsondbglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbRequest;
+class QJsonDbWatcher;
+
+class QJsonDbConnectionPrivate;
+class Q_JSONDB_EXPORT QJsonDbConnection : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString socketName READ socketName WRITE setSocketName)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(bool autoReconnectEnabled READ isAutoReconnectEnabled WRITE setAutoReconnectEnabled)
+
+public:
+ QJsonDbConnection(QObject *parent = 0);
+ ~QJsonDbConnection();
+
+ void setSocketName(const QString &);
+ QString socketName() const;
+
+ enum ErrorCode {
+ NoError = 0
+ };
+
+ enum Status {
+ Unconnected = 0,
+ Connecting = 1,
+ Authenticating = 2,
+ Connected = 3
+ };
+ Status status() const;
+
+ void setAutoReconnectEnabled(bool value);
+ bool isAutoReconnectEnabled() const;
+
+ QList<QJsonDbRequest *> pendingRequests() const;
+
+public Q_SLOTS:
+ void connectToServer();
+ void disconnectFromServer();
+
+ bool send(QJsonDbRequest *request);
+ bool cancel(QJsonDbRequest *request);
+ void cancelPendingRequests();
+
+ bool addWatcher(QJsonDbWatcher *watcher);
+ bool removeWatcher(QJsonDbWatcher *watcher);
+
+Q_SIGNALS:
+ void connected();
+ void disconnected();
+ void error(QtJsonDb::QJsonDbConnection::ErrorCode error, const QString &message);
+
+ // signals for properties
+ void statusChanged(QtJsonDb::QJsonDbConnection::Status newStatus);
+
+private:
+ Q_DISABLE_COPY(QJsonDbConnection)
+ Q_DECLARE_PRIVATE(QJsonDbConnection)
+ QScopedPointer<QJsonDbConnectionPrivate> d_ptr;
+
+ Q_PRIVATE_SLOT(d_func(), void _q_onDisconnected())
+ Q_PRIVATE_SLOT(d_func(), void _q_onConnected())
+ Q_PRIVATE_SLOT(d_func(), void _q_onError(QLocalSocket::LocalSocketError))
+ Q_PRIVATE_SLOT(d_func(), void _q_onTimer())
+ Q_PRIVATE_SLOT(d_func(), void _q_onReceivedObject(QJsonObject))
+ Q_PRIVATE_SLOT(d_func(), void _q_onAuthFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_onAuthError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))
+
+ friend class QJsonDbWatcher;
+};
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_CONNECTION_H
diff --git a/src/client/qjsondbconnection_p.h b/src/client/qjsondbconnection_p.h
new file mode 100644
index 00000000..2c5d9558
--- /dev/null
+++ b/src/client/qjsondbconnection_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_CONNECTION_P_H
+#define JSONDB_CONNECTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QWeakPointer>
+#include <QLocalSocket>
+#include <QTimer>
+
+#include "qjsondbglobal.h"
+#include "qjsondbconnection.h"
+#include "qjsondbrequest.h"
+
+#include "jsonstream.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbConnectionPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbConnection)
+public:
+ QJsonDbConnectionPrivate(QJsonDbConnection *q);
+
+ inline QString serverSocketName() const
+ { return socketName.isEmpty() ? QStringLiteral("qt5jsondb") : socketName; }
+ inline bool shouldAutoReconnect() const
+ { return autoReconnectEnabled && !explicitDisconnect; }
+
+ void _q_onConnected();
+ void _q_onDisconnected();
+ void _q_onError(QLocalSocket::LocalSocketError);
+ void _q_onTimer();
+ void _q_onReceivedObject(const QJsonObject &);
+ void _q_onAuthFinished();
+ void _q_onAuthError(QtJsonDb::QJsonDbRequest::ErrorCode, const QString &);
+
+ void handleRequestQueue();
+ void initWatcher(QJsonDbWatcher *);
+ void removeWatcher(QJsonDbWatcher *);
+ void reactivateAllWatchers();
+
+ QJsonDbConnection *q_ptr;
+ QString socketName;
+ QJsonDbConnection::Status status;
+ QByteArray authenticationToken;
+ QByteArray defaultAuthenticationToken;
+ bool autoReconnectEnabled;
+ bool explicitDisconnect;
+ QTimer timeoutTimer;
+
+ QLocalSocket *socket;
+ JsonStream::JsonStream *stream;
+
+ int lastRequestId;
+ QWeakPointer<QJsonDbRequest> currentRequest;
+ QList<QWeakPointer<QJsonDbRequest> > pendingRequests;
+
+ QMap<QString, QWeakPointer<QJsonDbWatcher> > watchers; // uuid->watcher map
+};
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_CONNECTION_P_H
diff --git a/src/client/qjsondbglobal.h b/src/client/qjsondbglobal.h
new file mode 100644
index 00000000..187ca357
--- /dev/null
+++ b/src/client/qjsondbglobal.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_GLOBAL_H
+#define JSONDB_GLOBAL_H
+
+#include "QtCore/qglobal.h"
+
+#if defined(QT_JSONDB_LIB)
+# define Q_JSONDB_EXPORT Q_DECL_EXPORT
+#else
+# define Q_JSONDB_EXPORT Q_DECL_IMPORT
+#endif
+
+#if defined(QT_NAMESPACE)
+# define QT_BEGIN_NAMESPACE_JSONDB namespace QT_NAMESPACE { namespace QtJsonDb {
+# define QT_END_NAMESPACE_JSONDB } }
+# define QT_USE_NAMESPACE_JSONDB using namespace QT_NAMESPACE::QtJsonDb;
+# define QT_PREPEND_NAMESPACE_JSONDB(name) ::QT_NAMESPACE::QtJsonDb::name
+#else
+# define QT_BEGIN_NAMESPACE_JSONDB namespace QtJsonDb {
+# define QT_END_NAMESPACE_JSONDB }
+# define QT_USE_NAMESPACE_JSONDB using namespace QtJsonDb;
+# define QT_PREPEND_NAMESPACE_JSONDB(name) ::QtJsonDb::name
+#endif
+
+// a workaround for moc - if there is a header file that doesn't use jsondb
+// namespace, we still force moc to do "using namespace" but the namespace have to
+// be defined, so let's define an empty namespace here
+QT_BEGIN_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_GLOBAL_H
diff --git a/src/client/qjsondbobject.cpp b/src/client/qjsondbobject.cpp
new file mode 100644
index 00000000..45d2d03d
--- /dev/null
+++ b/src/client/qjsondbobject.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbobject.h"
+#include "qjsondbstrings_p.h"
+
+#include <QCryptographicHash>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+struct Uuid
+{
+ uint data1;
+ ushort data2;
+ ushort data3;
+ uchar data4[8];
+};
+
+static const Uuid JsonDbNamespace = {0x6ba7b810, 0x9dad, 0x11d1, { 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
+
+/*!
+ \class QJsonDbObject
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbObject class provides convenience api for constructing
+ object that should be persisted to QtJsonDb.
+
+ Objects that are persisted to Qt JsonDb are uniquely identified by
+ \l{http://en.wikipedia.org/wiki/Universally_unique_identifier}{UUID} which
+ value is stored inside an object in a special property \c{_uuid}. QJsonDbObject
+ provides convenience api for generating uuid for a given object.
+
+ There are several "versions" (variations) of UUID described in the
+ specification, and for Qt JsonDb the two important ones are the following:
+
+ \list
+ \o version 3 constructs uuid from a given string (usually, uri)
+ \o version 4 generates a random uuid
+ \endlist
+
+ Uuid version 3 makes a deterministic uuid from a given string, that can be
+ reproduce later on, which is a very useful feature allowing to make a
+ unique object identifier from a user-given string. For example if one saves
+ file meta-data into Qt JsonDb, it might be convienient to deterministically
+ generate uuid from a given file path. In Qt JsonDb this is achieved by
+ constructing uuid from the string using
+ QJsonDbObject::createUuidFromString() call.
+
+ Creating random uuid:
+
+ \code
+ #include <QtJsonDb/qjsondbobject.h>
+ QT_USE_NAMESPACE_JSONDB
+
+ QJsonDbObject object;
+ object.setUuid(QJsonDbObject::createUuid());
+ object.insert(QStringLiteral("name"), QLatin1String("Tor"));
+ object.insert(QStringLiteral("foo"), 42);
+ \endcode
+
+ QJsonDbObject::createUuidFromString() function can be used to conveniently
+ construct deterministic uuid for a given string identifier:
+
+ \code
+ #include <QtJsonDb/qjsondbobject.h>
+ QT_USE_NAMESPACE_JSONDB
+
+ QJsonDbObject object;
+ // uuid from "Tor" is created and assigned to the object
+ object.setUuid(QJsonDbObject::createUuidFromString(QStringLiteral("Tor")));
+ object.insert(QStringLiteral("name"), QLatin1String("Tor"));
+ object.insert(QStringLiteral("foo"), 42);
+ \endcode
+*/
+
+/*!
+ Constructs an empty object.
+*/
+QJsonDbObject::QJsonDbObject()
+{ }
+
+/*!
+ Constructs object from the given \a other QJsonObject.
+*/
+QJsonDbObject::QJsonDbObject(const QJsonObject &other)
+ : QJsonObject(other)
+{ }
+
+/*!
+ Assigns \a other to this object.
+*/
+QJsonDbObject &QJsonDbObject::operator=(const QJsonObject &other)
+{
+ *static_cast<QJsonObject *>(this) = other;
+ return *this;
+}
+
+/*!
+ Returns uuid of an object, if present.
+
+ This is the same as retrieving a value of the \c _uuid element.
+
+ \sa setUuid()
+*/
+QUuid QJsonDbObject::uuid() const
+{
+ return QUuid(value(JsonDbStrings::Property::uuid()).toString());
+}
+
+/*!
+ Inserts the given \a uuid into the map.
+
+ This is the same as calling \c {insert(QStringLiteral("_uuid"), uuid.toString())}.
+
+ \sa uuid(), createUuidFromString()
+*/
+void QJsonDbObject::setUuid(const QUuid &uuid)
+{
+ insert(JsonDbStrings::Property::uuid(), uuid.toString());
+}
+
+/*!
+ Returns random uuid that can be used to identify an object.
+
+ This is exactly the same as calling QUuid::createUuid()
+
+ \sa createUuidFromString()
+*/
+QUuid QJsonDbObject::createUuid()
+{
+ return QUuid::createUuid();
+}
+
+/*!
+ Returns deterministic uuid that can be used to identify given \a identifier.
+
+ The uuid is generated using QtJsonDb UUID namespace on a value of the
+ given \a identifier.
+
+ \sa createUuid()
+*/
+QUuid QJsonDbObject::createUuidFromString(const QString &identifier)
+{
+ const QUuid ns(JsonDbNamespace.data1, JsonDbNamespace.data2, JsonDbNamespace.data3,
+ JsonDbNamespace.data4[0], JsonDbNamespace.data4[1], JsonDbNamespace.data4[2],
+ JsonDbNamespace.data4[3], JsonDbNamespace.data4[4], JsonDbNamespace.data4[5],
+ JsonDbNamespace.data4[6], JsonDbNamespace.data4[7]);
+ return QUuid::createUuidV3(ns, identifier);
+}
+
+///*!
+// Inserts a new item with the key \a key and a value of \a value.
+
+// If there is already an item with the key \a key then that item's value
+// is replaced with \a value.
+
+// Returns an iterator pointing to the inserted item.
+
+// \sa QJsonObject::insert()
+//*/
+//QJsonObject::iterator QJsonDbObject::insert(const QString &key, const QUuid &value)
+//{
+// return insert(key, QJsonValue(value.toString())); // ### TODO: make QJsonObject store raw uuid
+//}
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbobject.h b/src/client/qjsondbobject.h
new file mode 100644
index 00000000..a086e315
--- /dev/null
+++ b/src/client/qjsondbobject.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_OBJECT_H
+#define JSONDB_OBJECT_H
+
+#include <QtCore/QJsonObject>
+#include <QtCore/QUuid>
+
+#include <QtJsonDb/qjsondbglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class Q_JSONDB_EXPORT QJsonDbObject : public QJsonObject
+{
+public:
+ QJsonDbObject();
+ QJsonDbObject(const QJsonObject &other);
+
+ QJsonDbObject &operator=(const QJsonObject &other);
+
+ QUuid uuid() const;
+ void setUuid(const QUuid &uuid);
+
+ static QUuid createUuid();
+ static QUuid createUuidFromString(const QString &id);
+
+// ### TODO: put me back after QUuid has explicit constructors
+// QJsonObject::iterator insert(const QString &key, const QUuid &value);
+//#if !defined(Q_NO_USING_KEYWORD)
+// using QJsonObject::insert;
+//#else
+// inline QJsonObject::iterator insert(const QString &key, const QJsonValue &value)
+// { return QJsonObject::insert(key, value); }
+//#endif
+};
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_OBJECT_H
diff --git a/src/client/qjsondbreadrequest.cpp b/src/client/qjsondbreadrequest.cpp
new file mode 100644
index 00000000..ce654327
--- /dev/null
+++ b/src/client/qjsondbreadrequest.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbreadrequest_p.h"
+#include "qjsondbstrings_p.h"
+
+#include <QJsonArray>
+#include <QVariant>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+/*!
+ \class QJsonDbReadRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbReadRequest class allows to query database.
+
+ See \l{Expression Examples} for documentation on the query string format.
+
+ \code
+ QJsonDbReadRequest *request = new QJsonDbReadRequest;
+ request->setQuery(QStringLiteral("[?_type=\"Foo\"]"));
+ connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ QJsonDbConnection *connection = new QJsonDbConnection;
+ connection->send(request);
+ \endcode
+*/
+/*!
+ \enum QJsonDbReadRequest::ErrorCode
+
+ This enum describes database connection errors for read requests that can
+ be emitted by the error() signal.
+
+ \value NoError
+ \value MissingQuery Missing query field.
+ \value MissingType Missing _type field.
+ \value InvalidLimit Invalid limit field
+ \value InvalidPartition Invalid partition.
+
+ \sa error(), QJsonDbRequest::ErrorCode
+*/
+
+QJsonDbReadRequestPrivate::QJsonDbReadRequestPrivate(QJsonDbReadRequest *q)
+ : QJsonDbRequestPrivate(q), queryLimit(-1)
+{
+}
+
+/*!
+ Constructs a new query request object with the given \a parent.
+*/
+QJsonDbReadRequest::QJsonDbReadRequest(QObject *parent)
+ : QJsonDbRequest(new QJsonDbReadRequestPrivate(this), parent)
+{
+}
+
+/*!
+ Constructs a new query request object with the given \a query string and \a
+ parent.
+*/
+QJsonDbReadRequest::QJsonDbReadRequest(const QString &query, QObject *parent)
+ : QJsonDbRequest(new QJsonDbReadRequestPrivate(this), parent)
+{
+ Q_D(QJsonDbReadRequest);
+ d->query = query;
+}
+
+/*!
+ \internal
+*/
+QJsonDbReadRequest::QJsonDbReadRequest(QJsonDbReadRequestPrivate *dd, QObject *parent)
+ : QJsonDbRequest(dd, parent)
+{
+ Q_ASSERT(dd != 0);
+}
+
+/*!
+ Destroys the request object.
+*/
+QJsonDbReadRequest::~QJsonDbReadRequest()
+{
+}
+
+/*!
+ \property QJsonDbReadRequest::query
+
+ \brief the query string
+
+ Specifies the query string for the request in the format described in
+ \l{Expression Examples}.
+
+ \sa queryLimit, bindValue()
+*/
+QString QJsonDbReadRequest::query() const
+{
+ Q_D(const QJsonDbReadRequest);
+ return d->query;
+}
+
+void QJsonDbReadRequest::setQuery(const QString &query)
+{
+ Q_D(QJsonDbReadRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->query = query;
+}
+
+/*!
+ \property QJsonDbReadRequest::queryLimit
+ \brief the limit of a query
+
+ Specifies the maximum amount of amount that should be fetched from the
+ database.
+
+ \sa query
+*/
+int QJsonDbReadRequest::queryLimit() const
+{
+ Q_D(const QJsonDbReadRequest);
+ return d->queryLimit;
+}
+
+void QJsonDbReadRequest::setQueryLimit(int limit)
+{
+ Q_D(QJsonDbReadRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->queryLimit = limit;
+}
+
+/*!
+ Set the placeholder \a placeHolder to be bound to value \a val in the query
+ string. Note that '%' is the only placeholder mark supported by the query.
+ The marker '%' should not be included in the \a placeHolder name.
+
+ \code
+ QJsonDbReadRequest *query = new QJsonDbReadRequest;
+ query->setQuery(QStringLiteral("[?_type=\"Person\"][?firstName = %name]"));
+ query->bindValue(QStringLiteral("name"), QLatin1String("Malcolm"));
+ \endcode
+
+ \sa query, boundValue(), boundValues(), clearBoundValues()
+*/
+void QJsonDbReadRequest::bindValue(const QString &placeHolder, const QJsonValue &val)
+{
+ Q_D(QJsonDbReadRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->bindings.insert(placeHolder, val);
+}
+
+/*!
+ Returns the value for the \a placeHolder.
+*/
+QJsonValue QJsonDbReadRequest::boundValue(const QString &placeHolder) const
+{
+ Q_D(const QJsonDbReadRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ return d->bindings.value(placeHolder, QJsonValue(QJsonValue::Undefined));
+}
+
+/*!
+ Returns a map of the bound values.
+*/
+QMap<QString,QJsonValue> QJsonDbReadRequest::boundValues() const
+{
+ Q_D(const QJsonDbReadRequest);
+ return d->bindings;
+}
+
+/*!
+ Clears all bound values.
+*/
+void QJsonDbReadRequest::clearBoundValues()
+{
+ Q_D(QJsonDbReadRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->bindings.clear();
+}
+
+/*!
+ \property QJsonDbReadRequest::stateNumber
+
+ Returns a database state number that the query was executed on.
+
+ The property is populated after started() signal was emitted.
+
+ \sa started()
+*/
+quint32 QJsonDbReadRequest::stateNumber() const
+{
+ Q_D(const QJsonDbReadRequest);
+ return d->stateNumber;
+}
+
+/*!
+ \property QJsonDbReadRequest::sortKey
+
+ Returns a field that was used as a sort key when executing a query.
+
+ The results of the query are ordered by that field.
+
+ The property is populated after started() signal was emitted.
+
+ \sa started(), takeResults()
+*/
+QString QJsonDbReadRequest::sortKey() const
+{
+ Q_D(const QJsonDbReadRequest);
+ return d->sortKey;
+}
+
+QJsonObject QJsonDbReadRequestPrivate::getRequest() const
+{
+ Q_Q(const QJsonDbReadRequest);
+ QJsonObject object;
+ object.insert(JsonDbStrings::Property::query(), query);
+ if (queryLimit != -1)
+ object.insert(JsonDbStrings::Property::queryLimit(), queryLimit);
+ QVariant v = q->property("queryOffset");
+ if (v.isValid())
+ object.insert(JsonDbStrings::Property::queryOffset(), v.toInt());
+ if (!bindings.isEmpty()) {
+ QJsonObject b;
+ QMap<QString, QJsonValue>::const_iterator it, e;
+ for (it = bindings.begin(), e = bindings.end(); it != e; ++it)
+ b.insert(it.key(), it.value());
+ object.insert(JsonDbStrings::Property::bindings(), b);
+ }
+ QJsonObject request;
+ request.insert(JsonDbStrings::Protocol::action(), JsonDbStrings::Protocol::query());
+ request.insert(JsonDbStrings::Protocol::object(), object);
+ request.insert(JsonDbStrings::Protocol::partition(), partition);
+ request.insert(JsonDbStrings::Protocol::requestId(), requestId);
+ return request;
+}
+
+void QJsonDbReadRequestPrivate::handleResponse(const QJsonObject &response)
+{
+ Q_Q(QJsonDbReadRequest);
+
+ stateNumber = static_cast<quint32>(response.value(JsonDbStrings::Property::state()).toDouble());
+ sortKey = response.value(JsonDbStrings::Property::sortKey()).toString();
+
+ setStatus(QJsonDbRequest::Receiving);
+ emit q->started();
+
+ QJsonArray list = response.value(JsonDbStrings::Protocol::data()).toArray();
+ results.reserve(results.size() + list.size());
+ foreach (const QJsonValue &v, list)
+ results.append(v.toObject());
+
+ emit q->resultsAvailable(results.size());
+ setStatus(QJsonDbRequest::Finished);
+ emit q->finished();
+}
+
+void QJsonDbReadRequestPrivate::handleError(int code, const QString &message)
+{
+ Q_Q(QJsonDbReadRequest);
+ setStatus(QJsonDbRequest::Error);
+ emit q->error(QJsonDbRequest::ErrorCode(code), message);
+}
+
+/*!
+ \class QJsonDbReadObjectRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbReadObjectRequest class allows to retrieve one object by its UUID.
+
+ To retrieve object content for a known uuid:
+
+ \code
+ QJsonDbReadObjectRequest *request = new QJsonDbReadObjectRequest(this);
+ request->setUuid(objectUuid);
+ connect(request, SIGNAL(objectAvailable(QJsonObject), this, SLOT(onObjectAvailable(QJsonObject)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connection->send(request);
+ \endcode
+*/
+
+QJsonDbReadObjectRequestPrivate::QJsonDbReadObjectRequestPrivate(QJsonDbReadObjectRequest *q)
+ : QJsonDbReadRequestPrivate(q)
+{
+}
+
+/*!
+ Constructs a new QJsonDbReadObjectRequest object with the given \a parent.
+*/
+QJsonDbReadObjectRequest::QJsonDbReadObjectRequest(QObject *parent)
+ : QJsonDbReadRequest(parent)
+{
+ connect(this, SIGNAL(finished()), this, SLOT(_q_onFinished()));
+}
+
+/*!
+ Constructs a new QJsonDbReadObjectRequest object with the given \a parent
+ to retrieve content of the object with the given \a uuid.
+*/
+QJsonDbReadObjectRequest::QJsonDbReadObjectRequest(const QUuid &uuid, QObject *parent)
+ : QJsonDbReadRequest(parent)
+{
+ connect(this, SIGNAL(finished()), this, SLOT(_q_onFinished()));
+ setUuid(uuid);
+}
+
+/*!
+ \property QJsonDbReadObjectRequest::uuid
+ Specifies UUID of the object to retrieve from the database.
+*/
+QUuid QJsonDbReadObjectRequest::uuid() const
+{
+ Q_D(const QJsonDbReadObjectRequest);
+ return d->uuid;
+}
+
+void QJsonDbReadObjectRequest::setUuid(const QUuid &uuid)
+{
+ Q_D(QJsonDbReadObjectRequest);
+ d->uuid = uuid;
+ setQuery(QStringLiteral("[?_uuid = %uuid]"));
+ bindValue(QStringLiteral("uuid"), uuid.toString());
+}
+
+void QJsonDbReadObjectRequestPrivate::_q_onFinished()
+{
+ Q_Q(QJsonDbReadObjectRequest);
+ if (results.size() != 1) {
+ qWarning() << "QJsonDbReadObjectRequest: instead of 1 object, got" << results.size() << "object(s)";
+ return;
+ }
+ QJsonObject object = results.at(0);
+ emit q->objectAvailable(object);
+}
+
+/*!
+ \fn void QJsonDbReadObjectRequest::objectAvailable(const QJsonObject &object)
+
+ This signal is emitted when the request is complete and the \a object was
+ successfully retrieve from the database.
+
+ This is just a convenience signal that can be used instead of finished().
+
+ \sa error()
+*/
+
+#include "moc_qjsondbreadrequest.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbreadrequest.h b/src/client/qjsondbreadrequest.h
new file mode 100644
index 00000000..8fb14ab1
--- /dev/null
+++ b/src/client/qjsondbreadrequest.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_READ_REQUEST_H
+#define JSONDB_READ_REQUEST_H
+
+#include <QObject>
+#include <QJsonValue>
+#include <QJsonObject>
+
+#include <QtJsonDb/qjsondbrequest.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbReadRequestPrivate;
+class Q_JSONDB_EXPORT QJsonDbReadRequest : public QJsonDbRequest
+{
+ Q_OBJECT
+ Q_PROPERTY(QString query READ query WRITE setQuery)
+ Q_PROPERTY(int queryLimit READ queryLimit WRITE setQueryLimit)
+
+ Q_PROPERTY(quint32 stateNumber READ stateNumber)
+ Q_PROPERTY(QString sortKey READ sortKey)
+
+public:
+ QJsonDbReadRequest(QObject *parent = 0);
+ QJsonDbReadRequest(const QString &query, QObject *parent = 0);
+ ~QJsonDbReadRequest();
+
+ enum ErrorCode {
+ NoError = QJsonDbRequest::NoError,
+ InvalidPartition = QJsonDbRequest::InvalidPartition,
+ MissingQuery = QJsonDbRequest::MissingQuery,
+ MissingType = QJsonDbRequest::MissingType,
+ InvalidLimit = QJsonDbRequest::InvalidLimit
+ };
+
+ QString query() const;
+ void setQuery(const QString &);
+
+ int queryLimit() const;
+ void setQueryLimit(int limit);
+
+ void bindValue(const QString &placeHolder, const QJsonValue &val);
+ QJsonValue boundValue(const QString &placeHolder) const;
+ QMap<QString,QJsonValue> boundValues() const;
+ void clearBoundValues();
+
+ // query results. Data is only available after started() was emitted.
+ quint32 stateNumber() const;
+ QString sortKey() const;
+
+protected:
+ QJsonDbReadRequest(QJsonDbReadRequestPrivate *dd, QObject *parent);
+
+private:
+ Q_DISABLE_COPY(QJsonDbReadRequest)
+ Q_DECLARE_PRIVATE(QJsonDbReadRequest)
+};
+
+class QJsonDbReadObjectRequestPrivate;
+class Q_JSONDB_EXPORT QJsonDbReadObjectRequest : public QJsonDbReadRequest
+{
+ Q_OBJECT
+ Q_PROPERTY(QUuid uuid READ uuid WRITE setUuid)
+
+public:
+ QJsonDbReadObjectRequest(QObject *parent = 0);
+ QJsonDbReadObjectRequest(const QUuid &uuid, QObject *parent = 0);
+
+ QUuid uuid() const;
+ void setUuid(const QUuid &uuid);
+
+Q_SIGNALS:
+ void objectAvailable(const QJsonObject &object);
+
+private:
+ Q_DISABLE_COPY(QJsonDbReadObjectRequest)
+ Q_DECLARE_PRIVATE(QJsonDbReadObjectRequest)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_onFinished())
+};
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_READ_REQUEST_H
diff --git a/src/client/qjsondbreadrequest_p.h b/src/client/qjsondbreadrequest_p.h
new file mode 100644
index 00000000..0663758d
--- /dev/null
+++ b/src/client/qjsondbreadrequest_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_READ_REQUEST_P_H
+#define JSONDB_READ_REQUEST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QMap>
+#include <QUuid>
+
+#include "qjsondbrequest_p.h"
+#include "qjsondbreadrequest.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbReadRequestPrivate : public QJsonDbRequestPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbReadRequest)
+public:
+ QJsonDbReadRequestPrivate(QJsonDbReadRequest *q);
+
+ QJsonObject getRequest() const;
+ void handleResponse(const QJsonObject &);
+ void handleError(int, const QString &);
+
+ QString query;
+ int queryLimit;
+ QMap<QString, QJsonValue> bindings;
+
+ // query results
+ quint32 stateNumber;
+ QString sortKey;
+};
+
+class QJsonDbReadObjectRequestPrivate : public QJsonDbReadRequestPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbReadObjectRequest)
+public:
+ QJsonDbReadObjectRequestPrivate(QJsonDbReadObjectRequest *q);
+
+ void _q_onFinished();
+
+ QUuid uuid;
+};
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_READ_REQUEST_P_H
diff --git a/src/client/qjsondbrequest.cpp b/src/client/qjsondbrequest.cpp
new file mode 100644
index 00000000..f94853d0
--- /dev/null
+++ b/src/client/qjsondbrequest.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbrequest_p.h"
+
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+/*!
+ \class QJsonDbRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbRequest class provides common functionality for database requests.
+*/
+/*!
+ \enum QJsonDbRequest::ErrorCode
+
+ This enum describes database connection errors.
+
+ Error codes described by this enum are all possible error codes for all
+ request types. To get error codes for a particular request, follow requests
+ documentation - e.g. QJsonDbReadRequest::ErrorCode.
+
+ \value NoError
+ \value MissingQuery Missing query field.
+ \value InvalidLimit Invalid limit field
+ \value InvalidPartition Invalid partition.
+ \value MissingObject Invalid or missing "object" field.
+ \value MissingType Missing _type field
+*/
+/*!
+ \enum QJsonDbRequest::Status
+
+ This enum describes current request status.
+
+ \value Inactive
+ \value Queued The request is queued and pending to be sent.
+ \value Sent The request was successfully sent to the database and waiting for the reply.
+ \value Receiving The request started received reply and initial data is available.
+ \value Finished The request was successfully complete.
+ \value Canceled The request was canceled.
+ \value Error The request failed.
+*/
+
+QJsonDbRequestPrivate::QJsonDbRequestPrivate(QJsonDbRequest *q)
+ : q_ptr(q), status(QJsonDbRequest::Inactive), requestId(0), internal(false)
+{
+}
+
+/*!
+ \internal
+*/
+QJsonDbRequest::QJsonDbRequest(QJsonDbRequestPrivate *d, QObject *parent)
+ : QObject(parent), d_ptr(d)
+{
+ Q_ASSERT(d != 0);
+}
+
+/*!
+ Destroys the request object.
+*/
+QJsonDbRequest::~QJsonDbRequest()
+{
+}
+
+/*!
+ \property QJsonDbRequest::status
+ Specifies the current request status.
+ \sa statusChanged()
+*/
+QJsonDbRequest::Status QJsonDbRequest::status() const
+{
+ Q_D(const QJsonDbRequest);
+ return d->status;
+}
+
+/*!
+ \property QJsonDbRequest::partition
+ Specifies the target partition for the request.
+*/
+QString QJsonDbRequest::partition() const
+{
+ Q_D(const QJsonDbRequest);
+ return d->partition;
+}
+
+void QJsonDbRequest::setPartition(const QString &partition)
+{
+ Q_D(QJsonDbRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->partition = partition;
+}
+
+void QJsonDbRequestPrivate::setStatus(QJsonDbRequest::Status newStatus)
+{
+ Q_Q(QJsonDbRequest);
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged(status);
+ }
+}
+
+void QJsonDbRequestPrivate::setRequestId(int id)
+{
+ Q_Q(QJsonDbRequest);
+ requestId = id;
+ q->setProperty("requestId", QVariant::fromValue(requestId));
+}
+
+/*!
+ Returns the first \a amount of request results.
+
+ If amount is -1, retrieves all available results.
+
+ \sa resultsAvailable()
+*/
+QList<QJsonObject> QJsonDbRequest::takeResults(int amount)
+{
+ Q_D(QJsonDbRequest);
+ QList<QJsonObject> list;
+ if (amount < 0 || amount >= d->results.size()) {
+ list.swap(d->results);
+ } else {
+ list = d->results.mid(0, amount);
+ d->results.erase(d->results.begin(), d->results.begin() + amount);
+ }
+ return list;
+}
+
+/*!
+ \fn bool QJsonDbRequest::isActive() const
+
+ Returns true if the request is active, i.e. in either QJsonDbRequest::Queued
+ or QJsonDbRequest::Sent or QJsonDbRequest::Receiving state.
+
+ \sa status
+*/
+/*!
+ \fn void QJsonDbRequest::started()
+
+ This signal is emitted when the request has started receiving the reply and
+ some initial data is available.
+
+ \sa finished(), error(), resultsAvailable(), statusChanged()
+*/
+/*!
+ \fn void QJsonDbRequest::resultsAvailable(int amount)
+
+ This signal is emitted incrementally when the request received results. \a
+ amount specifies how many results are available so far. Received results
+ can be retrieved using takeResults() function.
+
+ \sa takeResults(), finished()
+*/
+/*!
+ \fn void QJsonDbRequest::finished()
+
+ This signal is emitted when the request was completed successfully.
+
+ \sa takeResults(), error(), statusChanged()
+*/
+/*!
+ \fn void QJsonDbRequest::error(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+
+ This signal is emitted when an error occured while processing the request.
+ \a code and \a message describe the error.
+
+ \sa finished(), statusChanged()
+*/
+/*!
+ \fn void QJsonDbRequest::statusChanged(QtJsonDb::QJsonDbRequest::Status newStatus);
+ This signal is emitted when state of the request changed to \a newStatus.
+ \sa status, finished(), error()
+*/
+
+#include "moc_qjsondbrequest.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbrequest.h b/src/client/qjsondbrequest.h
new file mode 100644
index 00000000..1b7fe17b
--- /dev/null
+++ b/src/client/qjsondbrequest.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_REQUEST_H
+#define JSONDB_REQUEST_H
+
+#include <QtCore/QObject>
+#include <QtCore/QJsonObject>
+
+#include <QtJsonDb/qjsondbglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbRequestPrivate;
+class Q_JSONDB_EXPORT QJsonDbRequest : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString partition READ partition WRITE setPartition)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+
+public:
+ ~QJsonDbRequest();
+
+ enum ErrorCode {
+ NoError = 0,
+// ### TODO: clean me up and move me to ReadRequest and WriteRequest
+// InvalidMessage = 1,
+// InvalidRequest = 2,
+ MissingObject = 3,
+// DatabaseError = 4,
+// MissingUUID = 5,
+ MissingType = 6,
+ MissingQuery = 7,
+ InvalidLimit = 8,
+// InvalidOffset = 9,
+// MismatchedNotifyId = 10,
+// InvalidActions = 11,
+// UpdatingStaleVersion = 12,
+// OperationNotPermitted = 13,
+// QuotaExceeded = 14,
+// FailedSchemaValidation = 15,
+// InvalidMap = 16,
+// InvalidReduce = 17,
+// InvalidSchemaOperation = 18,
+ InvalidPartition = 19,
+// InvalidIndexOperation = 20
+ DatabaseConnectionError = 21
+ };
+
+ enum Status {
+ Inactive = 0,
+ Canceled = 1,
+ Finished = 2,
+ Error = 3,
+ Queued = 4,
+ Sent = 5,
+ Receiving = 6
+ };
+ Status status() const;
+
+ bool isActive() const;
+
+ QString partition() const;
+ void setPartition(const QString &);
+
+ QList<QJsonObject> takeResults(int amount = -1);
+
+Q_SIGNALS:
+ void started();
+ void resultsAvailable(int amount);
+ void finished();
+ void error(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
+
+ // signals for properties
+ void statusChanged(QtJsonDb::QJsonDbRequest::Status newStatus);
+
+protected:
+ QJsonDbRequest(QJsonDbRequestPrivate *d, QObject *parent = 0);
+ QScopedPointer<QJsonDbRequestPrivate> d_ptr;
+
+private:
+ Q_DISABLE_COPY(QJsonDbRequest)
+ Q_DECLARE_PRIVATE(QJsonDbRequest)
+ friend class QJsonDbConnection;
+ friend class QJsonDbConnectionPrivate;
+};
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_REQUEST_H
diff --git a/src/client/qjsondbrequest_p.h b/src/client/qjsondbrequest_p.h
new file mode 100644
index 00000000..6e4bb0da
--- /dev/null
+++ b/src/client/qjsondbrequest_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_REQUEST_P_H
+#define JSONDB_REQUEST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QJsonObject>
+
+#include "qjsondbrequest.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbRequestPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbRequest)
+public:
+ QJsonDbRequestPrivate(QJsonDbRequest *q);
+ virtual ~QJsonDbRequestPrivate() { }
+
+ virtual QJsonObject getRequest() const = 0;
+ virtual void handleResponse(const QJsonObject &) = 0;
+ virtual void handleError(int, const QString &) = 0;
+
+ void setStatus(QJsonDbRequest::Status newStatus);
+ void setRequestId(int id);
+
+ QJsonDbRequest *q_ptr;
+ QString partition;
+ QJsonDbRequest::Status status;
+ int requestId;
+ bool internal; // marks internal requests e.g. notification and token auth.
+
+ QList<QJsonObject> results;
+};
+
+#define JSONDB_CHECK_REQUEST_STATUS \
+ if (d->status >= QJsonDbRequest::Queued) \
+ qWarning("QJsonDbRequest: should not change already queued request.");
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_REQUEST_P_H
diff --git a/src/client/qjsondbstrings_p.h b/src/client/qjsondbstrings_p.h
new file mode 100644
index 00000000..2f29c557
--- /dev/null
+++ b/src/client/qjsondbstrings_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_STRINGS_P_H
+#define JSONDB_STRINGS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtJsonDb/QtJsonDbGlobal>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+namespace JsonDbStrings {
+
+class Protocol
+{
+public:
+ static inline const QString action() { return QStringLiteral("action"); }
+ static inline const QString create() { return QStringLiteral("create"); }
+ static inline const QString update() { return QStringLiteral("update"); }
+ static inline const QString remove() { return QStringLiteral("remove"); }
+ static inline const QString query() { return QStringLiteral("find"); }
+ static inline const QString token() { return QStringLiteral("token"); }
+ static inline const QString changesSince() { return QStringLiteral("changesSince"); }
+ static inline const QString object() { return QStringLiteral("object"); }
+ static inline const QString partition() { return QStringLiteral("partition"); }
+ static inline const QString requestId() { return QStringLiteral("id"); }
+ static inline const QString result() { return QStringLiteral("result"); }
+ static inline const QString data() { return QStringLiteral("data"); }
+ static inline const QString changes() { return QStringLiteral("changes"); }
+ static inline const QString count() { return QStringLiteral("count"); }
+ static inline const QString stateNumber() { return QStringLiteral("stateNumber"); }
+ static inline const QString error() { return QStringLiteral("error"); }
+ static inline const QString errorCode() { return QStringLiteral("code"); }
+ static inline const QString errorMessage() { return QStringLiteral("message"); }
+ static inline const QString types() { return QStringLiteral("types"); }
+};
+
+class Property
+{
+public:
+ static inline const QString type() { return QStringLiteral("_type"); }
+ static inline const QString uuid() { return QStringLiteral("_uuid"); }
+ static inline const QString version() { return QStringLiteral("_version"); }
+ static inline const QString deleted() { return QStringLiteral("_deleted"); }
+ static inline const QString notify() { return QStringLiteral("notify"); }
+ static inline const QString query() { return QStringLiteral("query"); }
+ static inline const QString queryLimit() { return QStringLiteral("limit"); }
+ static inline const QString queryOffset() { return QStringLiteral("offset"); }
+ static inline const QString actions() { return QStringLiteral("actions"); }
+ static inline const QString bindings() { return QStringLiteral("bindings"); }
+ static inline const QString state() { return QStringLiteral("state"); }
+ static inline const QString sortKey() { return QStringLiteral("sortKey"); }
+ static inline const QString startingStateNumber() { return QStringLiteral("startingStateNumber"); }
+ static inline const QString currentStateNumber() { return QStringLiteral("currentStateNumber"); }
+};
+
+class Types
+{
+public:
+ static inline const QString notification() { return QStringLiteral("notification"); }
+};
+
+class Notification
+{
+public:
+ static inline const QString actionCreate() { return QStringLiteral("create"); }
+ static inline const QString actionUpdate() { return QStringLiteral("update"); }
+ static inline const QString actionRemove() { return QStringLiteral("remove"); }
+};
+
+class Partition
+{
+public:
+ static inline const QString system() { return QStringLiteral("com.nokia.qtjsondb.System"); }
+ static inline const QString ephemeral() { return QStringLiteral("com.nokia.qtjsondb.Ephemeral"); }
+};
+
+} // namespace JsonDbStrings
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_STRINGS_P_H
diff --git a/src/client/qjsondbwatcher.cpp b/src/client/qjsondbwatcher.cpp
new file mode 100644
index 00000000..d41f1bb4
--- /dev/null
+++ b/src/client/qjsondbwatcher.cpp
@@ -0,0 +1,432 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbwatcher_p.h"
+#include "qjsondbstrings_p.h"
+#include "qjsondbconnection_p.h"
+
+#include <QUuid>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+/*!
+ \class QJsonDbNotification
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbNotification class describes a database notification event.
+
+ This is a single notification event that is emitted by QJsonDbWatcher class
+ when an object matching a query string was changed in the database.
+
+ \sa QJsonDbWatcher::notificationsAvailable(), QJsonDbWatcher::takeNotifications()
+*/
+
+/*!
+ \internal
+*/
+QJsonDbNotification::QJsonDbNotification(const QJsonObject &object, QJsonDbWatcher::Action action, quint32 stateNumber)
+ : obj(object), act(action), state(stateNumber)
+{
+}
+
+/*!
+ Returns the object that matched notification.
+
+ \list
+
+ \o If the action() is QJsonDbWatcher::Created, the object contains the full
+ object that started matching the watcher query string.
+
+ \o If the action() is QJsonDbWatcher::Updated, the object contains the
+ latest version of the object.
+
+ \o If the action() is QJsonDbWatcher::Removed, the object contains the
+ \c{_uuid} and \c{_version} of the object that no longer matches the watcher
+ query string.
+
+ \endlist
+
+ \sa QJsonDbObject
+*/
+QJsonObject QJsonDbNotification::object() const
+{
+ return obj;
+}
+
+/*!
+ Returns the notification action.
+*/
+QJsonDbWatcher::Action QJsonDbNotification::action() const
+{
+ return act;
+}
+
+/*!
+ Returns the state number that corresponds to the object in notification.
+*/
+quint32 QJsonDbNotification::stateNumber() const
+{
+ return state;
+}
+
+QJsonDbWatcherPrivate::QJsonDbWatcherPrivate(QJsonDbWatcher *q)
+ : q_ptr(q), status(QJsonDbWatcher::Inactive),
+ actions(QJsonDbWatcher::All), initialStateNumber(0), lastStateNumber(0)
+{
+ uuid = QUuid::createUuid().toString();
+}
+
+/*!
+ \class QJsonDbWatcher
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbWatcher class allows to watch live database changes.
+
+ This class is used to configure what live database changes should result in
+ notification events. The notificationsAvailable() signal is emitted
+ whenever an object matching the given \l{QJsonDbWatcher::query}{query} was
+ created or updated or removed from the database (depending on the
+ \l{QJsonDbWatcher::watchedActions}{action}). Notification events can be
+ retrieved using the takeNotifications() functions.
+
+ Each change in the database corresponds to the identifier of the change - a
+ database state number - and QJsonDbWatcher class can be used to start
+ watching for notifications events starting from the given
+ initialStateNumber. The last state number that was known to the watcher can
+ be retrieved using \l{QJsonDbWatcher::lastStateNumber}{lastStateNumber}
+ property.
+
+ QJsonDbWatcher should be registered within the database connection with
+ QJsonDbConnection::addWatcher() function and only starts receiving database
+ change notifications after it was successfully registered and
+ \l{QJsonDbWatcher::Status}{status} was switched to QJsonDbWatcher::Active
+ state.
+
+ Whenever the database connection is established it re-activates all
+ registered watchers, hence the watcher will be re-activated automatically
+ if the connection to the database was dropped and established again.
+
+ \code
+ QtJsonDb::QJsonDbWatcher *watcher = new QtJsonDb::QJsonDbWatcher;
+ watcher->setQuery(QStringLiteral("[?_type=\"Foo\"]"));
+ QObject::connect(watcher, SIGNAL(notificationsAvailable(int)),
+ this, SLOT(onNotificationsAvailable(int)));
+ QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ QtJsonDb::QJsonDbConnection *connection = new QtJsonDb::QJsonDbConnection;
+ connection->addWatcher(watcher);
+ \endcode
+*/
+/*!
+ \enum QJsonDbWatcher::Action
+
+ This enum describes possible actions that can be watched. By default
+ watcher is set to watch All actions.
+
+ \value Created Watches for objects to start matching the given query string.
+ \value Updated Watches for modifications of objects matching the given query.
+ \value Removed Watches for objects that stop matching the given query string.
+ \value All A convenience value that specifies to watch for all possible actions.
+*/
+/*!
+ \enum QJsonDbWatcher::Status
+
+ This enum describes watcher status.
+
+ \value Inactive The watcher does not current watch database changes.
+ \value Activating The watcher is being activated.
+ \value Active The watcher is successfully setup to watch for live database changes.
+*/
+/*!
+ \enum QJsonDbWatcher::ErrorCode
+
+ This enum describes possible errors that can happen when activating the watcher.
+
+ \value NoError
+ \value InvalidActions the set of actions that was given is incorrect.
+ \value InvalidQuery the given query is incorrect.
+ \value InvalidPartition the given partition is incorrect.
+ \value InvalidStateNumber the given initialStateNumber is incorrect.
+*/
+
+/*!
+ Constructs a new QJsonDbWatcher object with a given \a parent.
+
+ \sa QJsonDbConnection::addWatcher()
+*/
+QJsonDbWatcher::QJsonDbWatcher(QObject *parent)
+ : QObject(parent), d_ptr(new QJsonDbWatcherPrivate(this))
+{
+
+}
+/*!
+ Destroys the QJsonDbWatcher object.
+*/
+QJsonDbWatcher::~QJsonDbWatcher()
+{
+ Q_D(QJsonDbWatcher);
+ if (d->status != QJsonDbWatcher::Inactive && d->connection)
+ d->connection.data()->d_func()->removeWatcher(this);
+}
+
+/*!
+ \property QJsonDbWatcher::status
+ Specifies the current watcher status.
+ \sa statusChanged()
+*/
+QJsonDbWatcher::Status QJsonDbWatcher::status() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->status;
+}
+
+/*!
+ \property QJsonDbWatcher::watchedActions
+ Specifies which actions the watcher is registered for.
+*/
+void QJsonDbWatcher::setWatchedActions(QJsonDbWatcher::Actions actions)
+{
+ Q_D(QJsonDbWatcher);
+ if (d->status != QJsonDbWatcher::Inactive)
+ qWarning("QJsonDbWatcher: should not change already active watcher.");
+ d->actions = actions;
+}
+
+QJsonDbWatcher::Actions QJsonDbWatcher::watchedActions() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->actions;
+}
+
+/*!
+ \property QJsonDbWatcher::query
+ Specifies the query this watcher is registered for.
+*/
+void QJsonDbWatcher::setQuery(const QString &query)
+{
+ Q_D(QJsonDbWatcher);
+ if (d->status != QJsonDbWatcher::Inactive)
+ qWarning("QJsonDbWatcher: should not change already active watcher.");
+ d->query = query;
+}
+
+QString QJsonDbWatcher::query() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->query;
+}
+
+/*!
+ \property QJsonDbWatcher::partition
+ Specifies the partition this watcher is registered for.
+*/
+void QJsonDbWatcher::setPartition(const QString &partition)
+{
+ Q_D(QJsonDbWatcher);
+ if (d->status != QJsonDbWatcher::Inactive)
+ qWarning("QJsonDbWatcher: should not change already active watcher.");
+ d->partition = partition;
+}
+
+QString QJsonDbWatcher::partition() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->partition;
+}
+
+/*!
+ \property QJsonDbWatcher::initialStateNumber
+
+ Specifies from which database state number the watcher should start
+ watching for notifications.
+
+ \sa lastStateNumber()
+*/
+void QJsonDbWatcher::setInitialStateNumber(quint32 stateNumber)
+{
+ Q_D(QJsonDbWatcher);
+ if (d->status != QJsonDbWatcher::Inactive)
+ qWarning("QJsonDbWatcher: should not change already active watcher.");
+ d->initialStateNumber = stateNumber;
+ d->lastStateNumber = 0; // reset last seen state number
+}
+
+quint32 QJsonDbWatcher::initialStateNumber() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->initialStateNumber;
+}
+
+/*!
+ \property QJsonDbWatcher::lastStateNumber
+
+ Specifies the last database state number the watcher received notifications for.
+
+ This property contains valid data only after watcher was successfully
+ activated (i.e. the watcher state was changed to QJsonDbWatcher::Active).
+
+ \sa lastStateNumberChanged(), status
+*/
+quint32 QJsonDbWatcher::lastStateNumber() const
+{
+ Q_D(const QJsonDbWatcher);
+ return d->lastStateNumber;
+}
+
+/*!
+ Returns the first \a amount of notification events from the watcher.
+
+ If amount is -1, retrieves all available notifications events.
+
+ \sa notificationsAvailable()
+*/
+QList<QJsonDbNotification> QJsonDbWatcher::takeNotifications(int amount)
+{
+ Q_D(QJsonDbWatcher);
+ QList<QJsonDbNotification> list;
+ if (amount < 0 || amount >= d->notifications.size()) {
+ list.swap(d->notifications);
+ } else {
+ list = d->notifications.mid(0, amount);
+ d->notifications.erase(d->notifications.begin(), d->notifications.begin() + amount);
+ }
+ return list;
+}
+
+void QJsonDbWatcherPrivate::setStatus(QJsonDbWatcher::Status newStatus)
+{
+ Q_Q(QJsonDbWatcher);
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged(status);
+ }
+}
+
+void QJsonDbWatcherPrivate::_q_onFinished()
+{
+ Q_Q(QJsonDbWatcher);
+ Q_ASSERT(status != QJsonDbWatcher::Inactive);
+ if (status == QJsonDbWatcher::Activating) {
+ // got a success reply to notification creation
+ QJsonDbRequest *request = qobject_cast<QJsonDbRequest *>(q->sender());
+ Q_ASSERT(request != 0);
+ if (request) {
+ QList<QJsonObject> objects = request->takeResults();
+ Q_ASSERT(objects.size() == 1);
+ version = objects.at(0).value(JsonDbStrings::Property::version()).toString();
+ }
+ setStatus(QJsonDbWatcher::Active);
+ } else {
+ // got a success reply to notification deletion
+ setStatus(QJsonDbWatcher::Inactive);
+ }
+}
+
+void QJsonDbWatcherPrivate::_q_onError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+{
+ Q_Q(QJsonDbWatcher);
+ Q_UNUSED(code);
+ QJsonDbWatcher::ErrorCode error = QJsonDbWatcher::InvalidQuery; // ### TODO:
+ emit q->error(error, message);
+}
+
+void QJsonDbWatcherPrivate::handleNotification(QJsonDbWatcher::Action action, const QJsonObject &object)
+{
+ Q_Q(QJsonDbWatcher);
+ if (!actions.testFlag(action))
+ return;
+ Q_ASSERT(!object.isEmpty());
+ quint32 stateNumber = 0; // ### TODO:
+ // lastStateNumber = stateNumber;
+ // emit q->lastStateNumberChanged(stateNumber);
+ QJsonDbNotification n(object, action, stateNumber);
+ notifications.append(n);
+ emit q->notificationsAvailable(notifications.size());
+}
+
+/*!
+ \fn bool QJsonDbWatcher::isInactive() const
+ Returns true if the status of the watcher is QJsonDbWatcher::Inactive.
+ \sa status
+*/
+/*!
+ \fn bool QJsonDbWatcher::isActivating() const
+ Returns true if the status of the watcher is QJsonDbWatcher::Activating.
+ \sa status
+*/
+/*!
+ \fn bool QJsonDbWatcher::isActive() const
+ Returns true if the status of the watcher is QJsonDbWatcher::Active.
+ \sa status
+*/
+/*!
+ \fn void QJsonDbWatcher::notificationsAvailable(int count)
+
+ This signal is emitted when the \l{QJsonDbWatcher::isActive()}{active}
+ watcher receives database notification events. \a count specifies how many
+ events are available so far.
+
+ \sa takeNotifications()
+*/
+/*!
+ \fn void QJsonDbWatcher::statusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus);
+ This signal is emitted when state of the watcher changed to \a newStatus.
+ \sa status
+*/
+/*!
+ \fn void QJsonDbWatcher::error(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
+
+ This signal is emitted when an error occured while activating the watcher.
+ \a code and \a message describe the error.
+*/
+/*!
+ \fn void QJsonDbWatcher::lastStateNumberChanged(int stateNumber);
+
+ This signal is emitted when the given \a stateNumber is fully processed -
+ all notifications for it were successfully received.
+
+ \sa lastStateNumber
+*/
+
+#include "moc_qjsondbwatcher.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbwatcher.h b/src/client/qjsondbwatcher.h
new file mode 100644
index 00000000..a86031d7
--- /dev/null
+++ b/src/client/qjsondbwatcher.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_WATCHER_H
+#define JSONDB_WATCHER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QJsonObject>
+#include <QtCore/QUuid>
+
+#include <QtJsonDb/qjsondbglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbNotification;
+class QJsonDbWatcherPrivate;
+class Q_JSONDB_EXPORT QJsonDbWatcher : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(Actions watchedActions READ watchedActions WRITE setWatchedActions)
+ Q_PROPERTY(QString query READ query WRITE setQuery)
+ Q_PROPERTY(QString partition READ partition WRITE setPartition)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(quint32 initialStateNumber READ initialStateNumber WRITE setInitialStateNumber)
+ Q_PROPERTY(quint32 lastStateNumber READ lastStateNumber NOTIFY lastStateNumberChanged)
+
+public:
+ enum Action {
+ Created = 0x01, // ### TODO: rename me to StartsMatching ?
+ Updated = 0x02,
+ Removed = 0x04,
+
+ All = 0xFF
+ };
+ Q_DECLARE_FLAGS(Actions, Action)
+
+ enum Status {
+ Inactive,
+ Activating,
+ Active
+ };
+ Status status() const;
+ inline bool isInactive() const { return status() == QJsonDbWatcher::Inactive; }
+ inline bool isActivating() const { return status() == QJsonDbWatcher::Activating; }
+ inline bool isActive() const { return status() == QJsonDbWatcher::Active; }
+
+ enum ErrorCode {
+ NoError = 0,
+ InvalidActions = 1,
+ InvalidQuery = 2,
+ InvalidPartition = 3,
+ InvalidStateNumber = 4
+ };
+
+ QJsonDbWatcher(QObject *parent = 0);
+ ~QJsonDbWatcher();
+
+ void setWatchedActions(Actions actions);
+ Actions watchedActions() const;
+
+ void setQuery(const QString &query);
+ QString query() const;
+
+ void setPartition(const QString &partition);
+ QString partition() const;
+
+ void setInitialStateNumber(quint32 stateNumber);
+ quint32 initialStateNumber() const;
+
+ quint32 lastStateNumber() const;
+
+ QList<QJsonDbNotification> takeNotifications(int amount = -1);
+
+Q_SIGNALS:
+ void notificationsAvailable(int count);
+ void statusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus);
+ void error(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
+
+ // signals for properties
+ void lastStateNumberChanged(int stateNumber);
+
+private:
+ Q_DECLARE_PRIVATE(QJsonDbWatcher)
+ QScopedPointer<QJsonDbWatcherPrivate> d_ptr;
+
+ Q_PRIVATE_SLOT(d_func(), void _q_onFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_onError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))
+
+ friend class QJsonDbConnection;
+ friend class QJsonDbConnectionPrivate;
+};
+
+class Q_JSONDB_EXPORT QJsonDbNotification
+{
+public:
+ QJsonDbNotification(const QJsonObject &object, QJsonDbWatcher::Action action, quint32 stateNumber);
+
+ QJsonObject object() const;
+ QJsonDbWatcher::Action action() const;
+ quint32 stateNumber() const;
+
+private:
+ QJsonObject obj;
+ QJsonDbWatcher::Action act;
+ quint32 state;
+
+ void *reserved;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QJsonDbWatcher::Actions)
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_WATCHER_H
diff --git a/src/client/qjsondbwatcher_p.h b/src/client/qjsondbwatcher_p.h
new file mode 100644
index 00000000..0773501e
--- /dev/null
+++ b/src/client/qjsondbwatcher_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_WATCHER_P_H
+#define JSONDB_WATCHER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QWeakPointer>
+
+#include "qjsondbwatcher.h"
+#include "qjsondbrequest.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbConnection;
+
+class QJsonDbWatcherPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbWatcher)
+public:
+ QJsonDbWatcherPrivate(QJsonDbWatcher *q);
+
+ void _q_onFinished();
+ void _q_onError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
+
+ void handleNotification(QJsonDbWatcher::Action action, const QJsonObject &object);
+ void setStatus(QJsonDbWatcher::Status newStatus);
+
+ QJsonDbWatcher *q_ptr;
+ QWeakPointer<QJsonDbConnection> connection;
+ QJsonDbWatcher::Status status;
+ QJsonDbWatcher::Actions actions;
+ QString query;
+ QString partition;
+ quint32 initialStateNumber;
+ quint32 lastStateNumber;
+
+ QList<QJsonDbNotification> notifications;
+
+ QString uuid; // ### TODO: make me QUuid after QJsonObject can store binary blob efficiently
+ QString version;
+};
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_WATCHER_P_H
diff --git a/src/client/qjsondbwriterequest.cpp b/src/client/qjsondbwriterequest.cpp
new file mode 100644
index 00000000..614fdd84
--- /dev/null
+++ b/src/client/qjsondbwriterequest.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsondbwriterequest_p.h"
+#include "qjsondbstrings_p.h"
+#include "qjsondbobject.h"
+
+#include <QJsonArray>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+/*!
+ \class QJsonDbWriteRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbWriteRequest class allows to put objects into the database.
+
+ \code
+ QJsonObject object;
+ object.insert(QStringLiteral("_type"), QLatin1String("Foo"));
+ object.insert(QStringLiteral("firstName"), QLatin1String("Malcolm"));
+ object.insert(QStringLiteral("lastName"), QLatin1String("Reinolds"));
+ QList<QJsonObject> objects;
+ objects.append(object);
+
+ QJsonDbWriteRequest *request = new QJsonDbWriteRequest;
+ request->setObjects(objects);
+ connect(request, SIGNAL(finished()), this, SLOT(onCreateFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onCreateError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ QJsonDbConnection *connection = new QJsonDbConnection;
+ connection->send(request);
+ \endcode
+
+ See derived classes that provide some optional convenience -
+ QJsonDbRemoveRequest to remove a list of objects, QJsonDbUpdateRequest to
+ modify a list of objects and QJsonDbCreateRequest to create a list of
+ objects.
+
+ \sa QJsonDbObject
+*/
+/*!
+ \enum QJsonDbWriteRequest::ErrorCode
+
+ This enum describes database connection errors for write requests that can
+ be emitted by the error() signal.
+
+ \value NoError
+ \value MissingObject Missing object field.
+
+ \sa error(), QJsonDbRequest::ErrorCode
+*/
+
+QJsonDbWriteRequestPrivate::QJsonDbWriteRequestPrivate(QJsonDbWriteRequest *q)
+ : QJsonDbRequestPrivate(q)
+{
+}
+
+/*!
+ Constructs a new write request object with the given \a parent.
+*/
+QJsonDbWriteRequest::QJsonDbWriteRequest(QObject *parent)
+ : QJsonDbRequest(new QJsonDbWriteRequestPrivate(this), parent)
+{
+}
+
+/*!
+ Destroys the request object.
+*/
+QJsonDbWriteRequest::~QJsonDbWriteRequest()
+{
+}
+
+/*!
+ \property QJsonDbWriteRequest::objects
+
+ \brief the list of objects to be written to the database
+*/
+void QJsonDbWriteRequest::setObjects(const QList<QJsonObject> &objects)
+{
+ Q_D(QJsonDbWriteRequest);
+ JSONDB_CHECK_REQUEST_STATUS;
+ d->objects = objects;
+}
+
+QList<QJsonObject> QJsonDbWriteRequest::objects() const
+{
+ Q_D(const QJsonDbWriteRequest);
+ return d->objects;
+}
+
+/*!
+ \property QJsonDbWriteRequest::stateNumber
+
+ Returns a database state number that the write request was executed on.
+
+ The property is populated after started() signal was emitted.
+
+ \sa started()
+*/
+quint32 QJsonDbWriteRequest::stateNumber() const
+{
+ Q_D(const QJsonDbWriteRequest);
+ return d->stateNumber;
+}
+
+QJsonObject QJsonDbWriteRequestPrivate::getRequest() const
+{
+ QJsonObject request;
+ request.insert(JsonDbStrings::Protocol::action(), JsonDbStrings::Protocol::update());
+ if (objects.size() == 0) {
+ return QJsonObject();
+ } else if (objects.size() == 1) {
+ request.insert(JsonDbStrings::Protocol::object(), objects.at(0));
+ } else {
+ QJsonArray array;
+ foreach (const QJsonObject &obj, objects)
+ array.append(obj);
+ request.insert(JsonDbStrings::Protocol::object(), array);
+ }
+ request.insert(JsonDbStrings::Protocol::partition(), partition);
+ request.insert(JsonDbStrings::Protocol::requestId(), requestId);
+ return request;
+}
+
+void QJsonDbWriteRequestPrivate::handleResponse(const QJsonObject &response)
+{
+ Q_Q(QJsonDbWriteRequest);
+ // sigh, fix the server response
+ if (response.contains(JsonDbStrings::Protocol::data())) {
+ QJsonArray data = response.value(JsonDbStrings::Protocol::data()).toArray();
+ foreach (const QJsonValue &v, data) {
+ QJsonObject object = v.toObject();
+ stateNumber = static_cast<quint32>(object.value(JsonDbStrings::Protocol::stateNumber()).toDouble());
+ QJsonObject obj;
+ obj.insert(JsonDbStrings::Property::uuid(), object.value(JsonDbStrings::Property::uuid()));
+ obj.insert(JsonDbStrings::Property::version(), object.value(JsonDbStrings::Property::version()));
+ results.append(obj);
+ }
+ } else {
+ stateNumber = static_cast<quint32>(response.value(JsonDbStrings::Protocol::stateNumber()).toDouble());
+ QJsonObject obj;
+ obj.insert(JsonDbStrings::Property::uuid(), response.value(JsonDbStrings::Property::uuid()));
+ obj.insert(JsonDbStrings::Property::version(), response.value(JsonDbStrings::Property::version()));
+ results.append(obj);
+ }
+ setStatus(QJsonDbRequest::Receiving);
+ emit q->started();
+ emit q->resultsAvailable(results.size());
+ setStatus(QJsonDbRequest::Finished);
+ emit q->finished();
+}
+
+void QJsonDbWriteRequestPrivate::handleError(int code, const QString &message)
+{
+ Q_Q(QJsonDbWriteRequest);
+ setStatus(QJsonDbRequest::Error);
+ emit q->error(QJsonDbRequest::ErrorCode(code), message);
+}
+
+/*!
+ \class QJsonDbCreateRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbCreateRequest class allows to create objects in the database.
+
+ This is a convenience api for QJsonDbWriteRequest that generates uuid for
+ the given object and puts it into QJsonDbWriteRequest.
+*/
+/*!
+ Creates a new QJsonDbCreateRequest object with the given \a parent to create
+ the given \a object in the database.
+*/
+QJsonDbCreateRequest::QJsonDbCreateRequest(const QJsonObject &object, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ QJsonDbObject obj = object;
+ if (obj.uuid().isNull())
+ obj.setUuid(QJsonDbObject::createUuid());
+ QList<QJsonObject> list;
+ list.append(obj);
+ setObjects(list);
+}
+
+/*!
+ Creates a new QJsonDbCreateRequest object with the given \a parent to create
+ the given list of \a objects in the database.
+*/
+QJsonDbCreateRequest::QJsonDbCreateRequest(const QList<QJsonObject> &objects, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ QList<QJsonObject> objs = objects;
+ for (int i = 0; i < objs.size(); ++i) {
+ QJsonObject &obj = objs[i];
+ if (!obj.contains(JsonDbStrings::Property::uuid()))
+ obj.insert(JsonDbStrings::Property::uuid(), QUuid::createUuid().toString());
+ }
+ setObjects(objects);
+}
+
+/*!
+ \class QJsonDbUpdateRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbUpdateRequest class allows to modify objects in the database.
+
+ This is a convenience api for QJsonDbWriteRequest that passes all given
+ objects to the write request.
+*/
+/*!
+ Creates a new QJsonDbUpdateRequest object with the given \a parent to update
+ the given \a object in the database.
+*/
+QJsonDbUpdateRequest::QJsonDbUpdateRequest(const QJsonObject &object, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ QJsonDbObject obj = object;
+ if (obj.uuid().isNull()) {
+ qWarning() << "QJsonDbUpdateRequest: couldn't update an object that doesn't have uuid";
+ return;
+ }
+ QList<QJsonObject> list;
+ list.append(obj);
+ setObjects(list);
+}
+
+/*!
+ Creates a new QJsonDbUpdateRequest object with the given \a parent to update
+ the given list of \a objects in the database.
+*/
+QJsonDbUpdateRequest::QJsonDbUpdateRequest(const QList<QJsonObject> &objects, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ for (int i = 0; i < objects.size(); ++i) {
+ QJsonDbObject obj = objects.at(i);
+ if (obj.uuid().isNull()) {
+ qWarning() << "QJsonDbUpdateRequest: couldn't update an object that doesn't have uuid";
+ return;
+ }
+ }
+ setObjects(objects);
+}
+
+/*!
+ \class QJsonDbRemoveRequest
+ \inmodule QtJsonDb
+
+ \brief The QJsonDbRemoveRequest class allows to delete objects from the database.
+
+ This is a convenience api for QJsonDbWriteRequest that marks the given
+ objects to be deleted and puts them into QJsonDbWriteRequest.
+*/
+/*!
+ Creates a new QJsonDbRemoveRequest object with the given \a parent to remove
+ the given \a object from the database.
+*/
+QJsonDbRemoveRequest::QJsonDbRemoveRequest(const QJsonObject &object, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ QJsonObject obj = object;
+ if (!obj.value(JsonDbStrings::Property::deleted()).toBool())
+ obj.insert(JsonDbStrings::Property::deleted(), QJsonValue(true));
+ QList<QJsonObject> list;
+ list.append(obj);
+ setObjects(list);
+}
+
+/*!
+ Creates a new QJsonDbRemoveRequest object with the given \a parent to remove
+ the given list of \a objects from the database.
+*/
+QJsonDbRemoveRequest::QJsonDbRemoveRequest(const QList<QJsonObject> &objects, QObject *parent)
+ : QJsonDbWriteRequest(parent)
+{
+ QList<QJsonObject> objs = objects;
+ for (int i = 0; i < objs.size(); ++i) {
+ QJsonObject &obj = objs[i];
+ if (!obj.value(JsonDbStrings::Property::deleted()).toBool())
+ obj.insert(JsonDbStrings::Property::deleted(), QJsonValue(true));
+ }
+ setObjects(objs);
+}
+
+#include "moc_qjsondbwriterequest.cpp"
+
+QT_END_NAMESPACE_JSONDB
diff --git a/src/client/qjsondbwriterequest.h b/src/client/qjsondbwriterequest.h
new file mode 100644
index 00000000..ee4fcb94
--- /dev/null
+++ b/src/client/qjsondbwriterequest.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_WRITE_REQUEST_H
+#define JSONDB_WRITE_REQUEST_H
+
+#include <QtCore/QObject>
+#include <QtCore/QJsonObject>
+
+#include <QtJsonDb/qjsondbrequest.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbWriteRequestPrivate;
+class Q_JSONDB_EXPORT QJsonDbWriteRequest : public QJsonDbRequest
+{
+ Q_OBJECT
+ Q_PROPERTY(QList<QJsonObject> objects READ objects WRITE setObjects)
+
+ Q_PROPERTY(quint32 stateNumber READ stateNumber)
+
+public:
+ QJsonDbWriteRequest(QObject *parent = 0);
+ ~QJsonDbWriteRequest();
+
+ enum ErrorCode {
+ NoError = QJsonDbRequest::NoError,
+ MissingObject = QJsonDbRequest::MissingObject
+ };
+
+ void setObjects(const QList<QJsonObject> &);
+ QList<QJsonObject> objects() const;
+
+ // read request results. Data is only available after started() was emitted.
+ quint32 stateNumber() const;
+
+private:
+ Q_DISABLE_COPY(QJsonDbWriteRequest)
+ Q_DECLARE_PRIVATE(QJsonDbWriteRequest)
+};
+
+class Q_JSONDB_EXPORT QJsonDbCreateRequest : public QJsonDbWriteRequest
+{
+public:
+ QJsonDbCreateRequest(const QJsonObject &object, QObject *parent = 0);
+ QJsonDbCreateRequest(const QList<QJsonObject> &objects, QObject *parent = 0);
+};
+
+class Q_JSONDB_EXPORT QJsonDbUpdateRequest : public QJsonDbWriteRequest
+{
+public:
+ QJsonDbUpdateRequest(const QJsonObject &object, QObject *parent = 0);
+ QJsonDbUpdateRequest(const QList<QJsonObject> &objects, QObject *parent = 0);
+};
+
+class Q_JSONDB_EXPORT QJsonDbRemoveRequest : public QJsonDbWriteRequest
+{
+public:
+ QJsonDbRemoveRequest(const QJsonObject &object, QObject *parent = 0);
+ QJsonDbRemoveRequest(const QList<QJsonObject> &objects, QObject *parent = 0);
+};
+
+QT_END_NAMESPACE_JSONDB
+
+QT_END_HEADER
+
+#endif // JSONDB_WRITE_REQUEST_H
diff --git a/src/client/qjsondbwriterequest_p.h b/src/client/qjsondbwriterequest_p.h
new file mode 100644
index 00000000..469cd302
--- /dev/null
+++ b/src/client/qjsondbwriterequest_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_WRITE_REQUEST_P_H
+#define JSONDB_WRITE_REQUEST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QMap>
+
+#include "qjsondbrequest_p.h"
+#include "qjsondbwriterequest.h"
+
+QT_BEGIN_NAMESPACE_JSONDB
+
+class QJsonDbWriteRequestPrivate : public QJsonDbRequestPrivate
+{
+ Q_DECLARE_PUBLIC(QJsonDbWriteRequest)
+public:
+ QJsonDbWriteRequestPrivate(QJsonDbWriteRequest *q);
+
+ QJsonObject getRequest() const;
+ void handleResponse(const QJsonObject &);
+ void handleError(int, const QString &);
+
+ QList<QJsonObject> objects;
+
+ // response data
+ quint32 stateNumber;
+};
+
+QT_END_NAMESPACE_JSONDB
+
+#endif // JSONDB_WRITE_REQUEST_P_H
diff --git a/src/clientcompat/clientcompat.pro b/src/clientcompat/clientcompat.pro
new file mode 100644
index 00000000..38b03f88
--- /dev/null
+++ b/src/clientcompat/clientcompat.pro
@@ -0,0 +1,42 @@
+TEMPLATE = lib
+TARGET = $$QT.jsondbcompat.name
+MODULE = jsondbcompat
+
+load(qt_module)
+load(qt_module_config)
+
+DESTDIR = $$QT.jsondbcompat.libs
+VERSION = $$QT.jsondbcompat.VERSION
+DEFINES += QT_ADDON_JSONDB_LIB
+
+QT = core network
+
+CONFIG += module create_prl
+MODULE_PRI = ../../modules/qt_jsondbcompat.pri
+
+include(../common/common.pri)
+
+HEADERS += qtjsondbcompatversion.h
+
+HEADERS += \
+ jsondb-error.h \
+ jsondb-client.h \
+ jsondb-object.h \
+ jsondb-client_p.h \
+ jsondb-connection_p.h \
+ jsondb-connection_p_p.h \
+ jsondb-query.h \
+ jsondb-oneshot_p.h \
+ jsondb-strings_p.h \
+ jsondb-notification.h
+
+SOURCES += \
+ jsondb-error.cpp \
+ jsondb-client.cpp \
+ jsondb-object.cpp \
+ jsondb-connection.cpp \
+ jsondb-query.cpp \
+ jsondb-oneshot.cpp \
+ jsondb-notification.cpp
+
+mac:QMAKE_FRAMEWORK_BUNDLE_NAME = $$QT.jsondbcompat.name
diff --git a/src/client/jsondb-client.cpp b/src/clientcompat/jsondb-client.cpp
index 36562c1d..36562c1d 100644
--- a/src/client/jsondb-client.cpp
+++ b/src/clientcompat/jsondb-client.cpp
diff --git a/src/client/jsondb-client.h b/src/clientcompat/jsondb-client.h
index 02f2d90b..02f2d90b 100644
--- a/src/client/jsondb-client.h
+++ b/src/clientcompat/jsondb-client.h
diff --git a/src/client/jsondb-client_p.h b/src/clientcompat/jsondb-client_p.h
index be891102..be891102 100644
--- a/src/client/jsondb-client_p.h
+++ b/src/clientcompat/jsondb-client_p.h
diff --git a/src/client/jsondb-connection.cpp b/src/clientcompat/jsondb-connection.cpp
index 76378109..76378109 100644
--- a/src/client/jsondb-connection.cpp
+++ b/src/clientcompat/jsondb-connection.cpp
diff --git a/src/client/jsondb-connection_p.h b/src/clientcompat/jsondb-connection_p.h
index 9e147901..9e147901 100644
--- a/src/client/jsondb-connection_p.h
+++ b/src/clientcompat/jsondb-connection_p.h
diff --git a/src/client/jsondb-connection_p_p.h b/src/clientcompat/jsondb-connection_p_p.h
index 3fe15d0b..3fe15d0b 100644
--- a/src/client/jsondb-connection_p_p.h
+++ b/src/clientcompat/jsondb-connection_p_p.h
diff --git a/src/client/jsondb-error.cpp b/src/clientcompat/jsondb-error.cpp
index 90c819ba..90c819ba 100644
--- a/src/client/jsondb-error.cpp
+++ b/src/clientcompat/jsondb-error.cpp
diff --git a/src/client/jsondb-error.h b/src/clientcompat/jsondb-error.h
index 2b860e85..2b860e85 100644
--- a/src/client/jsondb-error.h
+++ b/src/clientcompat/jsondb-error.h
diff --git a/src/client/jsondb-global.h b/src/clientcompat/jsondb-global.h
index a85524bf..a85524bf 100644
--- a/src/client/jsondb-global.h
+++ b/src/clientcompat/jsondb-global.h
diff --git a/src/client/jsondb-notification.cpp b/src/clientcompat/jsondb-notification.cpp
index 13191f89..13191f89 100644
--- a/src/client/jsondb-notification.cpp
+++ b/src/clientcompat/jsondb-notification.cpp
diff --git a/src/client/jsondb-notification.h b/src/clientcompat/jsondb-notification.h
index 860ab9f6..860ab9f6 100644
--- a/src/client/jsondb-notification.h
+++ b/src/clientcompat/jsondb-notification.h
diff --git a/src/client/jsondb-object.cpp b/src/clientcompat/jsondb-object.cpp
index ef8147dc..ca5ea2fa 100644
--- a/src/client/jsondb-object.cpp
+++ b/src/clientcompat/jsondb-object.cpp
@@ -161,7 +161,7 @@ void JsonDbObject::setUuid(const QUuid &uuid)
}
/*!
- Returns a new uuid that can be used to identificate given \a object.
+ Returns a new uuid that can be used to identify given \a object.
Note that the returned uuid might be unique on every invocation on the same
object, if the \a object doesn't have the \c{_id} property and there is no
diff --git a/src/client/jsondb-object.h b/src/clientcompat/jsondb-object.h
index 340bb7d5..340bb7d5 100644
--- a/src/client/jsondb-object.h
+++ b/src/clientcompat/jsondb-object.h
diff --git a/src/client/jsondb-oneshot.cpp b/src/clientcompat/jsondb-oneshot.cpp
index 6e8b20a0..6e8b20a0 100644
--- a/src/client/jsondb-oneshot.cpp
+++ b/src/clientcompat/jsondb-oneshot.cpp
diff --git a/src/client/jsondb-oneshot_p.h b/src/clientcompat/jsondb-oneshot_p.h
index 154935c8..154935c8 100644
--- a/src/client/jsondb-oneshot_p.h
+++ b/src/clientcompat/jsondb-oneshot_p.h
diff --git a/src/client/jsondb-query.cpp b/src/clientcompat/jsondb-query.cpp
index 3da03d7c..3da03d7c 100644
--- a/src/client/jsondb-query.cpp
+++ b/src/clientcompat/jsondb-query.cpp
diff --git a/src/client/jsondb-query.h b/src/clientcompat/jsondb-query.h
index 3e9ad6db..3e9ad6db 100644
--- a/src/client/jsondb-query.h
+++ b/src/clientcompat/jsondb-query.h
diff --git a/src/client/jsondb-strings_p.h b/src/clientcompat/jsondb-strings_p.h
index ba3ee7e0..ba3ee7e0 100644
--- a/src/client/jsondb-strings_p.h
+++ b/src/clientcompat/jsondb-strings_p.h
diff --git a/src/common/jsondb-error.h b/src/common/jsondb-error.h
index 681414e6..3a4989e6 100644
--- a/src/common/jsondb-error.h
+++ b/src/common/jsondb-error.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../client/jsondb-error.h"
+#include "../clientcompat/jsondb-error.h"
diff --git a/src/common/jsondb-global.h b/src/common/jsondb-global.h
index d4a928bd..1ad585a8 100644
--- a/src/common/jsondb-global.h
+++ b/src/common/jsondb-global.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../client/jsondb-global.h"
+#include "../clientcompat/jsondb-global.h"
diff --git a/src/common/jsondb-strings.h b/src/common/jsondb-strings.h
index 1e040980..dc0295b8 100644
--- a/src/common/jsondb-strings.h
+++ b/src/common/jsondb-strings.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../client/jsondb-strings_p.h"
+#include "../clientcompat/jsondb-strings_p.h"
diff --git a/src/imports/jsondb-listmodel/jsondb-listmodel.pro b/src/imports/jsondb-listmodel/jsondb-listmodel.pro
index dbf2c3c1..a6e7759b 100644
--- a/src/imports/jsondb-listmodel/jsondb-listmodel.pro
+++ b/src/imports/jsondb-listmodel/jsondb-listmodel.pro
@@ -3,7 +3,7 @@ TARGETPATH = QtAddOn/JsonDb
include(../qimportbase.pri)
-QT += network declarative jsondb-private
+QT += network declarative jsondbcompat-private
DESTDIR = $$QT.jsondb.imports/$$TARGETPATH
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
diff --git a/src/imports/jsondb/jsondb.pro b/src/imports/jsondb/jsondb.pro
index 7de69546..be983dbf 100644
--- a/src/imports/jsondb/jsondb.pro
+++ b/src/imports/jsondb/jsondb.pro
@@ -3,9 +3,9 @@ TARGETPATH = QtJsonDb
include(../qimportbase.pri)
-QT += network declarative jsondb-private
+QT += network declarative jsondbcompat-private
-DESTDIR = $$QT.jsondb.imports/$$TARGETPATH
+DESTDIR = $$QT.jsondbcompat.imports/$$TARGETPATH
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
qmldir.files += $$PWD/qmldir
diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri
index 0a7af1cb..70bf7ab9 100644
--- a/src/imports/qimportbase.pri
+++ b/src/imports/qimportbase.pri
@@ -20,7 +20,7 @@ mac {
QMLDIRFILE = $${_PRO_FILE_PWD_}/qmldir
}
copy2build.input = QMLDIRFILE
-copy2build.output = $$QT.jsondb.imports/$$TARGETPATH/qmldir
+copy2build.output = $$QT.jsondbcompat.imports/$$TARGETPATH/qmldir
!contains(TEMPLATE_PREFIX, vc):copy2build.variable_out = PRE_TARGETDEPS
copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy2build.name = COPY ${QMAKE_FILE_IN}
diff --git a/src/jsonstream/jsonstream.cpp b/src/jsonstream/jsonstream.cpp
new file mode 100644
index 00000000..f4d02d22
--- /dev/null
+++ b/src/jsonstream/jsonstream.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "jsonstream.h"
+
+#include <QDebug>
+#include <QDataStream>
+#include <QLocalSocket>
+#include <QAbstractSocket>
+#include <QtEndian>
+#include <QJsonDocument>
+
+#ifdef QT_DEBUG
+#include <QUdpSocket>
+#include <QDateTime>
+#include <QCoreApplication>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace JsonStream {
+
+JsonStream::JsonStream(QObject *parent)
+ : QObject(parent), mDevice(0)
+{
+}
+
+QIODevice *JsonStream::device() const
+{
+ return mDevice;
+}
+
+/** Set the device used by the JsonStream.
+ The stream does not take ownership of the device.
+*/
+void JsonStream::setDevice(QIODevice *device)
+{
+ if (mDevice) {
+ disconnect(mDevice, SIGNAL(readyRead()), this, SLOT(deviceReadyRead()));
+ disconnect(mDevice, SIGNAL(bytesWritten(qint64)), this, SLOT(deviceBytesWritten(qint64)));
+ disconnect(mDevice, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
+ }
+ mDevice = device;
+ if (mDevice) {
+ connect(mDevice, SIGNAL(readyRead()), this, SLOT(deviceReadyRead()));
+ connect(mDevice, SIGNAL(bytesWritten(qint64)), this, SLOT(deviceBytesWritten(qint64)));
+ connect(mDevice, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
+ }
+}
+
+bool JsonStream::send(const QJsonObject &object)
+{
+ Q_ASSERT(mDevice != 0);
+ QByteArray data = QJsonDocument(object).toBinaryData();
+ int shouldWrite = data.size();
+ if (mWriteBuffer.isEmpty()) {
+ int didWrite = mDevice->write(data);
+ if (didWrite < 0) {
+ qWarning() << "Error writing to socket" << mDevice->errorString();
+ } else if (didWrite < shouldWrite) {
+ mWriteBuffer = data.mid(didWrite);
+ }
+ QLocalSocket *s = qobject_cast<QLocalSocket *>(mDevice);
+ if (s)
+ s->flush();
+ } else {
+ qWarning() << "Buffering, slow down your writes";
+ mWriteBuffer.append(data);
+ }
+ return true;
+}
+
+void JsonStream::deviceReadyRead()
+{
+ while (!mDevice->atEnd()) {
+ int bytesAvailable = mDevice->bytesAvailable();
+ int offset = mReadBuffer.size();
+ mReadBuffer.resize(offset + bytesAvailable);
+ int bytesRead = mDevice->read(mReadBuffer.data()+offset, bytesAvailable);
+ if (bytesRead < 0) {
+ qWarning() << "Error reading from socket" << mDevice->errorString();
+ continue;
+ }
+ while (mReadBuffer.size()) {
+ QJsonDocument doc(QJsonDocument::fromBinaryData(mReadBuffer, QJsonDocument::Validate));
+ if (doc.isEmpty())
+ break;
+ receive(doc.object());
+ mReadBuffer = mReadBuffer.mid(doc.toBinaryData().size());
+ }
+ }
+}
+
+void JsonStream::deviceBytesWritten(qint64 bytes)
+{
+ Q_UNUSED(bytes);
+ if (!mWriteBuffer.isEmpty()) {
+ int didWrite = mDevice->write(mWriteBuffer);
+ mWriteBuffer = mWriteBuffer.mid(didWrite);
+ }
+}
+
+} // namespace JsonStream
+
+QT_END_NAMESPACE
+
+#include "moc_jsonstream.cpp"
diff --git a/src/jsonstream/jsonstream.h b/src/jsonstream/jsonstream.h
new file mode 100644
index 00000000..f76020ff
--- /dev/null
+++ b/src/jsonstream/jsonstream.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSON_STREAM_H
+#define JSON_STREAM_H
+
+#include <QObject>
+#include <QJsonObject>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+namespace JsonStream {
+
+class JsonStream : public QObject
+{
+ Q_OBJECT
+public:
+ explicit JsonStream(QObject *parent = 0);
+
+ QIODevice *device() const;
+ void setDevice(QIODevice *device);
+
+ bool send(const QJsonObject &document);
+
+Q_SIGNALS:
+ void receive(const QJsonObject &data);
+ void aboutToClose();
+
+protected slots:
+ void deviceReadyRead();
+ void deviceBytesWritten(qint64 bytes);
+
+private:
+ QIODevice *mDevice;
+ QByteArray mWriteBuffer;
+ QByteArray mReadBuffer;
+};
+
+} // namespace JsonStream
+
+QT_END_NAMESPACE
+
+#endif // JSON_STREAM_H
diff --git a/src/jsonstream/jsonstream.pri b/src/jsonstream/jsonstream.pri
new file mode 100644
index 00000000..6bbb9b79
--- /dev/null
+++ b/src/jsonstream/jsonstream.pri
@@ -0,0 +1,2 @@
+INCLUDEPATH += $$PWD
+LIBS_PRIVATE += -L../jsonstream -lqtjsondbjsonstream
diff --git a/src/jsonstream/jsonstream.pro b/src/jsonstream/jsonstream.pro
new file mode 100644
index 00000000..cb7ea280
--- /dev/null
+++ b/src/jsonstream/jsonstream.pro
@@ -0,0 +1,14 @@
+TARGET = qtjsondbjsonstream
+
+TEMPLATE = lib
+CONFIG += qt staticlib
+
+QT = core network
+
+HEADERS += jsonstream.h
+SOURCES += jsonstream.cpp
+
+# We don't need to install this tool, it's only used for building.
+# However we do have to make sure that 'make install' builds it.
+dummytarget.CONFIG = dummy_install
+INSTALLS += dummytarget
diff --git a/src/src.pro b/src/src.pro
index af8a6a83..33992b82 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,4 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
-SUBDIRS += 3rdparty daemon client imports
-
+SUBDIRS += 3rdparty jsonstream clientcompat client daemon imports
diff --git a/sync.profile b/sync.profile
index 00d1dc2a..218659e3 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,19 +1,22 @@
%modules = ( # path to module name map
- "QtAddOnJsonDb" => "$basedir/src/client",
+ "QtJsonDb" => "$basedir/src/client",
+ "QtJsonDbCompat" => "$basedir/src/clientcompat",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
);
%classnames = (
- "qtaddonjsondbversion.h" => "QtAddOnJsonDbVersion",
+ "qtjsondbversion.h" => "QtJsonDbVersion",
+ "qjsondbglobal.h" => "QtJsonDbGlobal",
);
%mastercontent = (
"core" => "#include <QtCore/QtCore>\n",
"network" => "#include <QtNetwork/QtNetwork>\n",
);
%modulepris = (
- "QtAddOnJsonDb" => "$basedir/modules/qt_jsondb.pri",
+ "QtJsonDb" => "$basedir/modules/qt_jsondb.pri",
+ "QtJsonDbCompat" => "$basedir/modules/qt_jsondbcompat.pri",
);
-$publicclassregexp = "JsonDb.+";
+$publicclassregexp = "QJsonDb.+";
# Module dependencies.
# Every module that is required to build this module should have one entry.
# Each of the module version specifiers can take one of the following values:
diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro
index 889f697d..3d35c27b 100644
--- a/tests/auto/client/client.pro
+++ b/tests/auto/client/client.pro
@@ -1,6 +1,6 @@
TARGET = tst_client
-QT = network testlib jsondb-private
+QT = network testlib jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondb-listmodel/jsondb-listmodel.pro b/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
index 7ec16b9b..1762cb24 100644
--- a/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
+++ b/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondb-listmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro b/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro
index 7bb5df17..df0d53d0 100644
--- a/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro
+++ b/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondbchangessinceobject
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondblistmodel/jsondblistmodel.pro b/tests/auto/jsondblistmodel/jsondblistmodel.pro
index 06bb8cef..67765a5b 100644
--- a/tests/auto/jsondblistmodel/jsondblistmodel.pro
+++ b/tests/auto/jsondblistmodel/jsondblistmodel.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondblistmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondbnotification/jsondbnotification.pro b/tests/auto/jsondbnotification/jsondbnotification.pro
index bb4ed13b..c418b550 100644
--- a/tests/auto/jsondbnotification/jsondbnotification.pro
+++ b/tests/auto/jsondbnotification/jsondbnotification.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondbnotification
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondbpartition/jsondbpartition.pro b/tests/auto/jsondbpartition/jsondbpartition.pro
index 328238bf..e067d7b7 100644
--- a/tests/auto/jsondbpartition/jsondbpartition.pro
+++ b/tests/auto/jsondbpartition/jsondbpartition.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondbpartition
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
index a146f595..365b9639 100644
--- a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
+++ b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondbqueryobject
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
index de72444f..ddf678f8 100644
--- a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
+++ b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
@@ -3,7 +3,7 @@ TARGET = tst_jsondbsortinglistmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
CONFIG += testcase
diff --git a/tests/benchmarks/client/client.pro b/tests/benchmarks/client/client.pro
index 6a934af3..9745c53d 100644
--- a/tests/benchmarks/client/client.pro
+++ b/tests/benchmarks/client/client.pro
@@ -3,7 +3,7 @@ TARGET = tst_bench_client
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib jsondb jsondb-private
+QT = core network testlib jsondb jsondbcompat-private
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
diff --git a/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro b/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro
index 78c9a142..f3ad2d9b 100644
--- a/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro
+++ b/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro
@@ -3,7 +3,7 @@ TARGET = tst_bench_listmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui declarative jsondb-private
+QT = core network testlib gui declarative jsondbcompat-private
CONFIG -= app_bundle
include($$PWD/../../shared/shared.pri)
diff --git a/tests/shared/shared.pri b/tests/shared/shared.pri
index e2522337..eba59a29 100644
--- a/tests/shared/shared.pri
+++ b/tests/shared/shared.pri
@@ -2,8 +2,12 @@ INCLUDEPATH += $$PWD
include(../../qtjsondb.pri)
-HEADERS += $$PWD/util.h $$PWD/clientwrapper.h $$PWD/qmltestutil.h
-SOURCES += $$PWD/clientwrapper.cpp
+HEADERS += $$PWD/util.h $$PWD/qmltestutil.h
+
+contains(QT, jsondbcompat|jsondbcompat-private) {
+ HEADERS += $$PWD/clientwrapper.h
+ SOURCES += $$PWD/clientwrapper.cpp
+}
RESOURCES += \
../../json.qrc
diff --git a/tools/jsondb-client/client.cpp b/tools/jsondb-client/client.cpp
index 080d797f..697abd12 100644
--- a/tools/jsondb-client/client.cpp
+++ b/tools/jsondb-client/client.cpp
@@ -39,28 +39,16 @@
**
****************************************************************************/
-#include <QSocketNotifier>
-#include <QCoreApplication>
-#include <QStringBuilder>
-#include <QMetaObject>
-#include <QThread>
-#include <QVariant>
-#include <QDir>
+#include "client.h"
+
#include <iostream>
#include <sstream>
#include <iomanip>
-#include "json.h"
-
-#include "client.h"
-
-QT_USE_NAMESPACE_JSONDB
-
extern bool gDebug;
const char* InputThread::commands[] = { "changesSince",
"create {\"",
- "find",
"help",
"notify create [?",
"notify remove [?",
@@ -228,24 +216,16 @@ Client::~Client()
bool Client::connectToServer()
{
QString socketName = ::getenv("JSONDB_SOCKET");
- if (socketName.isEmpty()) {
- mConnection = new QtAddOn::JsonDb::JsonDbClient(this);
- } else {
- mConnection = new QtAddOn::JsonDb::JsonDbClient(socketName, this);
- }
-
- connect(mConnection, SIGNAL(disconnected()), this, SLOT(disconnected()));
- connect(mConnection, SIGNAL(response(int,QVariant)),
- this, SLOT(response(int,QVariant)));
- connect(mConnection, SIGNAL(error(int,int,QString)),
- this, SLOT(error(int,int,QString)));
- connect(mConnection, SIGNAL(notified(QString,QVariant,QString)),
- this, SLOT(notified(QString,QVariant,QString)));
- connect(mConnection, SIGNAL(statusChanged()), this, SLOT(statusChanged()));
+ mConnection = new QtJsonDb::QJsonDbConnection(this);
+ if (!socketName.isEmpty())
+ mConnection->setSocketName(socketName);
- if (!mConnection->isConnected())
- qCritical() << "Not connected to the server yet... retrying";
+ connect(mConnection, SIGNAL(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)),
+ this, SLOT(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)));
+ connect(mConnection, SIGNAL(statusChanged(QtJsonDb::QJsonDbConnection::Status)),
+ this, SLOT(statusChanged(QtJsonDb::QJsonDbConnection::Status)));
+ mConnection->connectToServer();
return true;
}
@@ -257,64 +237,111 @@ void Client::interactiveMode()
mInputThread->start();
}
-void Client::disconnected()
+void Client::onNotificationsAvailable(int)
{
- qCritical() << "Lost connection to the server:" << mConnection->errorString();
+ QtJsonDb::QJsonDbWatcher *watcher = qobject_cast<QtJsonDb::QJsonDbWatcher *>(sender());
+ Q_ASSERT(watcher);
+ if (!watcher)
+ return;
+ QList<QtJsonDb::QJsonDbNotification> notifications = watcher->takeNotifications();
+ foreach (const QtJsonDb::QJsonDbNotification &n, notifications) {
+ QString actionString;
+ switch (n.action()) {
+ case QtJsonDb::QJsonDbWatcher::Created:
+ actionString = QStringLiteral("create"); break;
+ case QtJsonDb::QJsonDbWatcher::Updated:
+ actionString = QStringLiteral("update"); break;
+ case QtJsonDb::QJsonDbWatcher::Removed:
+ actionString = QStringLiteral("remove"); break;
+ case QtJsonDb::QJsonDbWatcher::All: break;
+ }
+
+ QString message = "Received notification: type " % actionString
+ % " for " % watcher->query() % " object:\n" % QJsonDocument(n.object()).toJson();
+ InputThread::print(message);
+ }
+ if (!mInputThread)
+ QCoreApplication::exit(0); // Non-interactive mode just stops
}
-void Client::notified(const QString &notify_uuid, const QVariant &object, const QString &action)
+void Client::onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode error, const QString &message)
{
- JsonWriter writer;
- writer.setAutoFormatting(true);
- QString buf = writer.toString(object);
-
- QString message = "Received notification: type " % action
- % " for " % notify_uuid % " object:\n" % buf;
- InputThread::print(message);
+ QtJsonDb::QJsonDbWatcher *watcher = qobject_cast<QtJsonDb::QJsonDbWatcher *>(sender());
+ Q_ASSERT(watcher);
+ if (!watcher)
+ return;
+ qDebug() << "Failed to create watcher:" << watcher->query() << error << message;
+}
- if (!mInputThread)
- QCoreApplication::exit(0); // Non-interactive mode just stops
+void Client::onNotificationStatusChanged(QtJsonDb::QJsonDbWatcher::Status)
+{
+ QtJsonDb::QJsonDbWatcher *watcher = qobject_cast<QtJsonDb::QJsonDbWatcher *>(sender());
+ Q_ASSERT(watcher);
+ if (!watcher)
+ return;
+ if (watcher->isActive())
+ qDebug() << "Watcher created:" << watcher->query();
}
-void Client::statusChanged()
+void Client::statusChanged(QtJsonDb::QJsonDbConnection::Status)
{
switch (mConnection->status()) {
- case JsonDbClient::Ready:
- qCritical() << "Connected to the server";
+ case QtJsonDb::QJsonDbConnection::Unconnected:
+ qCritical() << "Lost connection to the server";
break;
- case JsonDbClient::Error:
- qCritical() << "Cannot connect to the server:" << mConnection->errorString();
+ case QtJsonDb::QJsonDbConnection::Connecting:
+ qCritical() << "Connecting to the server...";
+ break;
+ case QtJsonDb::QJsonDbConnection::Authenticating:
+ qCritical() << "Authenticating...";
+ break;
+ case QtJsonDb::QJsonDbConnection::Connected:
+ qCritical() << "Connected to the server.";
break;
- default:
- return;
}
}
-void Client::response(int id, const QVariant &msg)
+void Client::error(QtJsonDb::QJsonDbConnection::ErrorCode error, const QString &message)
{
- Q_UNUSED(id);
- JsonWriter writer;
- writer.setAutoFormatting(true);
- QString buf = writer.toString(msg);
+ switch (error) {
+ case QtJsonDb::QJsonDbConnection::NoError:
+ Q_ASSERT(false);
+ break;
+ }
+}
- QString message = "Received message: " % buf;
- InputThread::print(message);
+void Client::onRequestFinished()
+{
+ QtJsonDb::QJsonDbRequest *request = qobject_cast<QtJsonDb::QJsonDbRequest *>(sender());
+ Q_ASSERT(request != 0);
+ if (!request)
+ return;
- mRequests.remove(id);
- if (mRequests.isEmpty())
- emit requestsProcessed();
+ QList<QJsonObject> objects = request->takeResults();
+
+ QString message = QLatin1String("Received ") + QString::number(objects.size()) + QLatin1String(" object(s):\n");
+ if (!objects.isEmpty()) {
+ message += QJsonDocument(objects.front()).toJson().trimmed();
+ for (int i = 1; i < objects.size(); ++i)
+ message += QLatin1String(",\n") + QJsonDocument(objects.at(i)).toJson().trimmed();
+ }
+ InputThread::print(message);
if (!mInputThread)
QCoreApplication::exit(0); // Non-interactive mode just stops
}
-void Client::error(int, int code, const QString &msg)
+void Client::pushRequest(QtJsonDb::QJsonDbRequest *request)
{
- QString message = "Received error " % QString().setNum(code) % ":" % msg;
- InputThread::print(message);
+ mRequests.append(request);
+}
- if (!mInputThread)
- QCoreApplication::exit(0); // Non-interactive mode just stops
+void Client::popRequest()
+{
+ QtJsonDb::QJsonDbRequest *request = mRequests.takeFirst();
+ delete request;
+ if (mRequests.isEmpty())
+ emit requestsProcessed();
}
void Client::usage()
@@ -332,7 +359,7 @@ void Client::usage()
<< " changesSince [partition:<name>] STATENUMBER [type1 type2 ...]" << std::endl
<< std::endl
<< "Convenience functions" << std::endl
- << " query STRING [offset [limit]]" << std::endl
+ << " query STRING [limit]" << std::endl
<< " find {\"query\": STRING}" << std::endl
<< " notify ACTIONS QUERY" << std::endl
<< " create { \"_type\": \"notification\"," << std::endl
@@ -380,19 +407,13 @@ bool Client::processCommand(const QString &command)
} else if (cmd == "help") {
usage();
} else if (cmd == "query") {
- int offset = 0, limit = -1;
+ int limit = -1;
int idx = rest.lastIndexOf(']');
if (idx != -1) {
QStringList list = rest.mid(idx+1).split(' ');
int i = 0;
for (; i < list.size(); ++i) {
if (!list.at(i).trimmed().isEmpty()) {
- offset = list.at(i).toInt();
- break;
- }
- }
- for (++i; i < list.size(); ++i) {
- if (!list.at(i).trimmed().isEmpty()) {
limit = list.at(i).toInt();
break;
}
@@ -400,97 +421,98 @@ bool Client::processCommand(const QString &command)
rest.truncate(idx+1);
}
if (gDebug)
- qDebug() << "Sending query:" << QVariant(rest);
- mRequests << mConnection->query(rest, offset, limit, partition);
+ qDebug() << "Sending query:" << rest;
+ QtJsonDb::QJsonDbReadRequest *request = new QtJsonDb::QJsonDbReadRequest(this);
+ request->setPartition(partition);
+ request->setQuery(rest);
+ request->setQueryLimit(limit);
+ connect(request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
+ connect(request, SIGNAL(finished()), this, SLOT(popRequest()));
+ pushRequest(request);
+ mConnection->send(request);
} else if (cmd == "notify") {
int s = rest.indexOf(' ');
if (s <= 0)
return false;
QStringList alist = rest.left(s).split(QRegExp(","), QString::SkipEmptyParts);
- QtAddOn::JsonDb::JsonDbClient::NotifyTypes actions;
+ QtJsonDb::QJsonDbWatcher::Actions actions;
foreach (const QString &s, alist) {
- JsonDbClient::NotifyType type = JsonDbClient::NotifyType(0);
+ QtJsonDb::QJsonDbWatcher::Action action = QtJsonDb::QJsonDbWatcher::Action(0);
if (s == QLatin1String("create"))
- type = JsonDbClient::NotifyCreate;
- if (s == QLatin1String("remove"))
- type = JsonDbClient::NotifyRemove;
- if (s == QLatin1String("update"))
- type = JsonDbClient::NotifyUpdate;
- if (type == JsonDbClient::NotifyType(0)) {
+ action = QtJsonDb::QJsonDbWatcher::Created;
+ else if (s == QLatin1String("remove"))
+ action = QtJsonDb::QJsonDbWatcher::Removed;
+ else if (s == QLatin1String("update"))
+ action = QtJsonDb::QJsonDbWatcher::Updated;
+ if (action == QtJsonDb::QJsonDbWatcher::Action(0)) {
InputThread::print("uknown notification type" % s);
return false;
}
- actions |= type;
+ actions |= action;
}
QString query = rest.mid(s+1).trimmed();
if (gDebug)
qDebug() << "Creating notification:" << alist << ":" << query;
- mRequests << mConnection->notify(actions, query, partition);
- } else if (cmd == "remove") {
- rest = rest.trimmed();
- bool isquery = false;
- int i = 0;
- const int len = rest.length();
- if (i < len) {
- if (rest.at(i++) == QLatin1Char('[')) {
- while (i < len && rest.at(i) == QLatin1Char(' ')) ++i;
- if (i < len && rest.at(i) == QLatin1Char('?'))
- isquery = true;
- }
- }
- if (isquery) {
- // if not json format, then it is a query
- if (gDebug)
- qDebug() << "Sending remove for:" << rest;
- mRequests << mConnection->remove(rest);
- } else {
- JsonReader parser;
- bool ok = parser.parse(rest);
- if (!ok) {
- InputThread::print("Unable to parse: " % rest);
- usage();
- return false;
- }
- QVariant arg = parser.result();
- if (gDebug)
- qDebug() << "Sending remove:" << arg;
- mRequests << mConnection->remove(arg, partition);
- }
- } else if (cmd == "create" || cmd == "update" || cmd == "find" ) {
- JsonReader parser;
- bool ok = parser.parse(rest);
- if (!ok) {
+ QtJsonDb::QJsonDbWatcher *watcher = new QtJsonDb::QJsonDbWatcher(this);
+ watcher->setPartition(partition);
+ watcher->setQuery(query);
+ watcher->setWatchedActions(actions);
+ connect(watcher, SIGNAL(notificationsAvailable(int)), this, SLOT(onNotificationsAvailable(int)));
+ connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
+ this, SLOT(onNotificationStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
+ connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ mConnection->addWatcher(watcher);
+ } else if (cmd == "create" || cmd == "update" || cmd == "remove") {
+ QJsonDocument doc = QJsonDocument::fromJson(rest.toUtf8());
+ if (doc.isEmpty()) {
InputThread::print("Unable to parse: " % rest);
usage();
return false;
}
- QVariant arg = parser.result();
if (gDebug)
- qDebug() << "Sending" << cmd << ":" << arg;
- int id = 0;
- QMetaObject::invokeMethod(mConnection, cmd.toLatin1(), Q_RETURN_ARG(int, id),
- Q_ARG(QVariant, arg), Q_ARG(QString, partition));
- mRequests << id;
+ qDebug() << "Sending" << cmd << ":" << doc;
+ QList<QJsonObject> objects;
+ if (doc.isObject()) {
+ objects.append(doc.object());
+ } else {
+ foreach (const QJsonValue &value, doc.array())
+ objects.append(value.toObject());
+ }
+ QtJsonDb::QJsonDbWriteRequest *request = 0;
+ if (cmd == "create")
+ request = new QtJsonDb::QJsonDbCreateRequest(objects);
+ else if (cmd == "update")
+ request = new QtJsonDb::QJsonDbUpdateRequest(objects);
+ else if (cmd == "remove")
+ request = new QtJsonDb::QJsonDbRemoveRequest(objects);
+ else
+ Q_ASSERT(false);
+ request->setPartition(partition);
+ connect(request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
+ connect(request, SIGNAL(finished()), this, SLOT(popRequest()));
+ pushRequest(request);
+ mConnection->send(request);
} else if (cmd == "changesSince") {
- int stateNumber = 0;
- QStringList types;
- QStringList args = rest.split(" ");
+// int stateNumber = 0;
+// QStringList types;
+// QStringList args = rest.split(" ");
- if (args.isEmpty()) {
- InputThread::print("Must specify the state number");
- usage();
- return false;
- }
+// if (args.isEmpty()) {
+// InputThread::print("Must specify the state number");
+// usage();
+// return false;
+// }
- stateNumber = args.takeFirst().trimmed().toInt();
+// stateNumber = args.takeFirst().trimmed().toInt();
- if (!args.isEmpty())
- types = args;
+// if (!args.isEmpty())
+// types = args;
- if (gDebug)
- qDebug() << "Sending changesSince: " << stateNumber << "types: " << types;
+// if (gDebug)
+// qDebug() << "Sending changesSince: " << stateNumber << "types: " << types;
- mRequests << mConnection->changesSince(stateNumber, types, partition);
+// mRequests << mConnection->changesSince(stateNumber, types, partition);
} else if (cmd == "connect") {
mConnection->connectToServer();
} else if (cmd == "disconnect") {
@@ -508,21 +530,21 @@ bool Client::processCommand(const QString &command)
bool Client::loadJsonFile(const QString &fileName)
{
- QFile file(fileName);
- if (!file.open(QFile::ReadOnly)) {
- if (gDebug)
- qDebug() << "Couldn't load file" << fileName;
- return false;
- }
- JsonReader parser;
- bool ok = parser.parse(file.readAll());
- file.close();
- if (!ok) {
- std::cout << "Unable to parse the content of the file" << qPrintable(fileName) << ":"
- << qPrintable(parser.errorString()) << std::endl;
- return false;
- }
- QVariant arg = parser.result();
- mRequests << mConnection->create(arg);
+// QFile file(fileName);
+// if (!file.open(QFile::ReadOnly)) {
+// if (gDebug)
+// qDebug() << "Couldn't load file" << fileName;
+// return false;
+// }
+// JsonReader parser;
+// bool ok = parser.parse(file.readAll());
+// file.close();
+// if (!ok) {
+// std::cout << "Unable to parse the content of the file" << qPrintable(fileName) << ":"
+// << qPrintable(parser.errorString()) << std::endl;
+// return false;
+// }
+// QVariant arg = parser.result();
+// mRequests << mConnection->create(arg);
return true;
}
diff --git a/tools/jsondb-client/client.h b/tools/jsondb-client/client.h
index fea34b24..fe523c7c 100644
--- a/tools/jsondb-client/client.h
+++ b/tools/jsondb-client/client.h
@@ -42,19 +42,11 @@
#ifndef CLIENT_H
#define CLIENT_H
-#include <QObject>
-#include <QThread>
-#include <QStringList>
-#include <QLocalSocket>
-#include <QSocketNotifier>
-#include <QFile>
+#include <QtCore>
+#include <QtJsonDb>
#include <histedit.h>
-#include "jsondb-client.h"
-
-
-
class InputThread : public QThread {
Q_OBJECT
public:
@@ -92,14 +84,19 @@ public slots:
bool loadJsonFile(const QString &fileName);
protected slots:
- void disconnected();
+ void error(QtJsonDb::QJsonDbConnection::ErrorCode, const QString &message);
+ void statusChanged(QtJsonDb::QJsonDbConnection::Status);
- void response(int, const QVariant &map);
- void error(int id, int code, const QString &message);
- void notified(const QString &notify_uuid, const QVariant &object, const QString &action);
- void statusChanged();
+ void onNotificationsAvailable(int);
+ void onNotificationStatusChanged(QtJsonDb::QJsonDbWatcher::Status);
+ void onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, const QString &);
-signals:
+ void onRequestFinished();
+
+ void pushRequest(QtJsonDb::QJsonDbRequest *);
+ void popRequest();
+
+Q_SIGNALS:
void requestsProcessed();
private:
@@ -107,8 +104,8 @@ private:
QSocketNotifier *mNotifier;
QFile *mInput;
- QtAddOn::JsonDb::JsonDbClient *mConnection;
- QSet<int> mRequests;
+ QtJsonDb::QJsonDbConnection *mConnection;
+ QList<QtJsonDb::QJsonDbRequest *> mRequests;
InputThread *mInputThread;
};
diff --git a/tools/jsondb-client/jsondb-client.pro b/tools/jsondb-client/jsondb-client.pro
index a8476771..f2326d98 100644
--- a/tools/jsondb-client/jsondb-client.pro
+++ b/tools/jsondb-client/jsondb-client.pro
@@ -4,12 +4,11 @@ DESTDIR = $$QT.jsondb.bins
target.path = $$[QT_INSTALL_PREFIX]/bin
INSTALLS += target
-QT = core network declarative jsondb
+QT = core jsondb
LIBS += -ledit
include(../../qtjsondb.pri)
-include(../../src/3rdparty/qjson/qjson.pri)
mac:CONFIG -= app_bundle
diff --git a/tools/tools.pro b/tools/tools.pro
index d6211f9a..4471e02f 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS += jsondb-client adb-dump
+SUBDIRS += jsondb-client